# coding=utf-8
import json
from django.db.models import Count
from docx import Document
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.shared import Cm
from docx.enum.table import WD_ROW_HEIGHT_RULE
import os
from pdf2image import convert_from_path
from copy import deepcopy
from decimal import Decimal

import re
from docx.enum.table import WD_TABLE_DIRECTION
from docx import Document
from docx.shared import Inches, Pt
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from bid.generate.tools.dawate import main_stream

from lxml import etree
import io
import sys
import pandas as pd
import shutil
import re
import threading
from PIL import ImageOps
from docx import Document
from docx.shared import RGBColor
from lxml import etree
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.enum.text import WD_UNDERLINE
import json_repair
from docx.enum.table import WD_CELL_VERTICAL_ALIGNMENT
from datetime import date
import datetime
import time
from shutil import copyfile
import traceback

from django.db.models import Q
from django.db.models import Avg

from zentao.settings import ROOT_FOLDER
from bid.generate.models import *
from bid.generate.tools.ai_generate_project_team import get_target_bid
from bid.generate.tools.projectFilter import projectFilter

# 定义命名空间
namespaces = {
    'w': 'http://schemas.openxmlformats.org/wordprocessingml/2006/main',
    'a': 'http://schemas.openxmlformats.org/drawingml/2006/main',
    'r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'
}

#商务文件生成
global_thread_all = {}
# basic_info_threadpool=[]


def table_create(hj_data,target_doc):
    # hj_data=json_repair.loads(hj_data)
    for row_idx, row in enumerate(hj_data):
        key_list = [i for i in list(row.keys()) if i not in ['code', 'type', 'date', 'company', 'file']]
    new_table = target_doc.add_table(rows=len(hj_data), cols=len(key_list))
    new_table.style = 'Table Grid'
    new_table.direction = WD_TABLE_DIRECTION.LTR
    # 设置自动调整模式为根据内容自动调整
    new_table.autofit = True
    # 创建表格 [{},{}]
    num_i = 1
    for row_idx, row in enumerate(hj_data):
        new_table.rows[row_idx].height = Cm(1.13)
        new_table.rows[row_idx].height_rule = WD_ROW_HEIGHT_RULE.AT_LEAST

        # for key_i,values_i,in row.items():
        key_list=[i for i in list(row.keys()) if i not in ['code','type','date','company','file']]
        key_d={'id':'序号','name':'获奖名称', 'prize':'级别', 'level':'获奖名次', 'reviewOrg':'评审/评定单位'}
        for col_idx, cell in enumerate(key_list):
            if row_idx==0:

                text = str(key_d[cell]).strip().replace(' ', '').replace('\n', '')
                cell_obj = new_table.cell(row_idx, col_idx)
                cell_obj.text = text
            else:
                if col_idx==0:
                    text =str(num_i)
                    num_i+=1
                else:
                    text = str(row[cell]).strip().replace(' ', '').replace('\n', '')
                cell_obj = new_table.cell(row_idx, col_idx)
                cell_obj.text = text
            cell_obj.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
            for paragraph in cell_obj.paragraphs:
                for run in paragraph.runs:
                    run.font.name = '宋体'
                    run._element.rPr.rFonts.set(qn('w:eastAsia'), run.font.name)
                    run.font.size = Pt(11.5)
                    if row_idx==0:
                        run.font.bold = True
                    # run.font.size = Pt(content_value[text]['font_size'])
                paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER

pool_sema = threading.BoundedSemaphore(5)
def dawate_streaming(extra={}):
    global pool_sema
    #     ls = []
    #     ls.append({"role": "user", "content": '肖建毅参与的项目有哪些'})
    #     ls.append({"role": "assistant", "content": '''1、2018年，负责组织建设广东电网有限责任公司应用级灾备中心一期建设项目、广东电网公司营销系统维护、广东电网公司资产系统维护、广东电网公司财务系统维护、广东电网公司人资系统维护、广东电网公司GIS维护等项目。
    # 2、2019年，负责组织建设广东电网有限责任公司应用级灾备中心二期建设项目、信息中心众测平台移动应用项目广东电网公司财务系统维护、广东电网公司信息中心1000号服务、广东电网公司营销系统维护、广东电网公司资产系统维护、广东电网公司财务系统维护、广东电网公司人资系统维护等项目。
    # 3、2020年，负责组织建设IOS系统实用化项目及面向电力行业的数据库智能运维模型及应用研究项目、广东电网公司信息中心1000号服务、广东电网公司营销系统维护、广东电网公司资产系统维护、广东电网公司财务系统维护、广东电网公司人资系统维护等项目。
    # 4、2021年，负责组织建设南方电网公司协同办公系统V2.0。'''})
    # for i in range(5):
    #     ls.append({"role": "user", "content": ''.join(["你是谁"]*5000)})
    #     ls.append({"role": "assistant", "content": '我是大瓦特'})

    # for i in ls:
    #     print(i)
    with pool_sema:
        # print('config_params:',config_params)
        # config_params = {
        #     'relAppId': '17987690',
        #     'appId': '17987868',
        #     'appSecret': '5570ea83260dbcad482a7c9175411d5e',
        #     # 'messages': [{"role": "user", "content": ''.join(["你是谁"]*5000)}]
        #     'messages': [{"role": "user", "content": content}]
        #     # 'messages': ls
        # }
        # config_params['messages'] = [{"role": "user", "content": content}]
        # answer = ''
        # print('输入数据：',content)
        answer = ''
        answer_bak = ''
        _type = extra.get('type', None)
        t_number = extra.get('number', None)
        key_i = extra.get('key_i', None)
        file_name = extra.get('filename', None)
        task_id = extra.get('task_id', None)
        content = extra.get('content', None)

        # print([content],'\n',[file_name],'\n================================\n')

        # print('结束')
        # time.sleep(10000)
        while not answer:
            response_content = main_stream(global_thread_all[task_id][file_name][f"{_type}{t_number}config_params"])
            # response_content = main_stream(config_params)
            # global_thread_all[task_id][file_name][f"{_type}{t_number}response_content"] = main_stream(config_params)
            try:
                while True:
                    a = next(response_content)
                    answer += a
                    answer_bak += a
                    # global_thread_all[task_id][file_name]['answer'] += a
                    # global_thread_all[task_id][file_name][f"{_type}{t_number}answer"] += next(global_thread_all[task_id][file_name][f"{_type}{t_number}response_content"])
                    # sys.stdout.write(f"\r{[a]}")
                    # sys.stdout.flush()
                    print(a, end='')
            except:

                pass

            answer=answer.split('</think>')[-1]

            # 如果没有答案，等5秒
            if not answer:
                time.sleep(5)
                print('大模型没有回复，重试中...')
            elif _type == '文本填充' and len(list(json_repair.loads(json_process(answer)))) != (''.join(content)).count(
                    '()'):
                # elif _type == '文本填充' :
                print('文本填充的长度', len(list(json_repair.loads(json_process(answer)))))
                print((''.join(content)).count('()'))
                answer = ''

        aaaa = '\n==========================================================================\n'
        folder = os.path.join('/media/977GB/wcj_work/禅道/新视图开发/zentao/bid/文档/ceshi', task_id)
        if not os.path.isdir(folder):
            os.makedirs(folder)
        with open(os.path.join(folder,f'{file_name}.txt'), 'a+') as f:
            f.writelines('\n'.join([aaaa,json.dumps(global_thread_all[task_id][file_name][f"{_type}{t_number}config_params"],
                                    ensure_ascii=False),aaaa,answer_bak,aaaa]))

        if _type == '文本填充':
            # s = json_repair.loads(json_process(global_thread_all[task_id][file_name][f"{_type}{t_number}answer"]))
            s = json_repair.loads(json_process(answer))
            global_thread_all[task_id][file_name]['文本填充'] = list(s)

        elif _type == '表格填充':
            # out_general = a.split('</think>')[-1]
            # out_general = global_thread_all[task_id][file_name][f"{_type}{t_number}answer"]
            out_general = answer
            # print('1',out_general)
            if 'json' in out_general:
                out_general = json_process(out_general)
            # print('2',out_general)
            result = json_repair.loads(out_general)
            print('表格填充结果：',result)

            global_thread_all[task_id][file_name]['表格填充'][0][t_number] = result
        elif _type=='结构化数据填报':
            # s = json_repair.loads(json_process(global_thread_all[task_id][file_name][f"{_type}{t_number}answer"]))
            s = json_repair.loads(json_process(answer))
            out_general = list(s)
            global_thread_all[task_id][file_name]['结构化数据填报'][0][str(key_i)] = out_general

    # return a
def trim_and_add_border(image):
    # 将图片转换为灰度图像，便于处理
    grayscale_image = image.convert('L')

    width = grayscale_image.width
    height = grayscale_image.height

    # 找到需要裁剪的边界
    def find_borders(img):
        invert_img = ImageOps.invert(img)
        bbox = invert_img.getbbox()
        return bbox

    borders = find_borders(grayscale_image)

    if not borders:
        borders = (0, 0, width, height)
    else:
        left, top, right, bottom = borders
        left = max(0, left - width // 20)
        right = min(width, right + width // 20)
        top = max(0, top - height // 20)
        bottom = min(height, bottom + height // 20)

        if (bottom - top) / (right - left) > 1.414:
            new_width = int((bottom - top) / 1.415)
            left = min(left, max(0, (width - new_width) // 2))
            right = max(right, min(width, new_width + (width - new_width) // 2))

            # print((bottom - top) / (right - left))

        borders = (left, top, right, bottom)

    trimmed_image = image.crop(borders)

    return trimmed_image


def copy_paragraph_from_doc_to_doc(source_paragraph, target_document):
    # 创建一个新的段落
    # if source_paragraph.text:
    new_paragraph = target_document.add_paragraph()

    # 复制段落样式
    new_paragraph.style = source_paragraph.style

    # 遍历源段落中的所有运行（运行包含文本和样式）
    for run in source_paragraph.runs:
        # 添加运行到新段落
        new_run = new_paragraph.add_run(run.text)

        # 复制运行样式
        new_run.font.name = run.font.name
        new_run.font.size = run.font.size
        new_run.font.bold = run.font.bold
        new_run.font.italic = run.font.italic
        new_run.font.underline = run.font.underline
        new_run.font.color.rgb = run.font.color.rgb

        # 复制段落格式
        new_paragraph.alignment = source_paragraph.alignment



def get_font_info(cell):
    font_info_all = []

    for paragraph in cell.paragraphs:
        for run in paragraph.runs:
            font_info = {}
            font = run.font
            font_name = font.name
            font_size = font.size.pt if font.size else None
            bold = font.bold
            italic = font.italic
            underline = font.underline
            font_info = {
                'text': run.text,
                'font_name': font_name,
                'font_size': font_size,
                'bold': bold,
                'italic': italic,
                'underline': underline
            }
            if not font_info['text'].replace(' ', '') and font_info['underline'] == True:
                font_info['text'] = f'()'

            font_info_all.append(font_info)
    # print('font_info_all', font_info_all)
    cell_text = ''.join([i['text'] for i in font_info_all])
    if font_info_all:
        font_info_all_all = {
            'text': cell_text,
            'font_name': font_info_all[0]['font_name'],
            'font_size': font_info_all[0]['font_size'],
            'bold': font_info_all[0]['bold'],
            'italic': font_info_all[0]['italic'],
            'underline': font_info_all[0]['underline']
        }
    else:
        font_info_all_all = {
            'text': cell_text,
            'font_name': None,
            'font_size': None,
            'bold': None,
            'italic': None,
            'underline': None}
    return font_info_all_all


from docx import Document
from docx.shared import Pt
import xml.etree.ElementTree as ET

def get_table_size(table):
    # 获取表格的XML元素
    table_xml = table._element
    # 解析XML以获取宽度信息

    table_width = table_xml.xpath('.//@w:tblW/@w:w')
    if table_width:
        table_width=table_width[0]
        # print('table_width:',table_width)
        # Word中的宽度单位为twips，1pt = 20twips
        table_width_pt = int(table_width) / 20
    else:
        table_width_pt=1


    # 初始化总高度
    table_height_pt = 0
    # 遍历每一行获取高度信息
    for row in table.rows:
        row_height = row._element.xpath('.//@w:trHeight/@w:h')
        if row_height:
            row_height=row_height[0]
            table_height_pt += int(row_height) / 20
        else:
            table_height_pt=1


    return table_width_pt, table_height_pt

def add_images_to_docx(directory,doc,text_num,path_all):
    # list_tree = file2tree(directory)
    # process_directory_tree(doc, list_tree, path_all, text_num)
    T_=1
    for dir_i in directory[0]:
        fields = [field.name for field in dir_i._meta.fields]
        # print('fields:',fields)
        if dir_i.name:
            title = doc.add_heading(level=1)
            run = title.add_run(f"{text_num}.{T_}.{dir_i.name}")
            run.font.name = '宋体'  # 设置字体
            run._element.rPr.rFonts.set(qn('w:eastAsia'), run.font.name)
            run.font.size = Pt(16)  # 设置字体大小
            run.font.bold = True  # 设置字体加粗
            run.font.color.rgb = RGBColor(0, 0, 0)
            title.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT

        path_list = {'companyChange', 'winBid', 'contractScan', 'contractTransfer', 'acceptanceCert', 'invoice'}
        nu_=1
        for i in path_list:
            if hasattr(dir_i, i) and getattr(dir_i, i):

                title = doc.add_heading(level=2)
                run = title.add_run(f"{text_num}.{T_}.{nu_}.{directory[1][i].replace('id', '')}")
                run.font.name = '宋体'  # 设置字体
                run._element.rPr.rFonts.set(qn('w:eastAsia'), run.font.name)
                run.font.size = Pt(16)  # 设置字体大小
                run.font.bold = True  # 设置字体加粗
                run.font.color.rgb = RGBColor(0, 0, 0)
                title.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT

                nu_ += 1


                s=getattr(dir_i, i)
                file_path = os.path.join(path_all, getattr(s, "path"))
                file_type = s.type

                if file_type == 'img':

                    # 添加图片到Word文档
                    doc.add_picture(file_path, width=Inches(6.0))  # 可以调整图片宽度
                    # 添加一个换行符
                    doc.add_paragraph()
                elif file_type == 'pdf':
                    images = convert_from_path(file_path)
                    # 遍历所有图片并将其添加到Word文档中
                    for image in images:
                        image = trim_and_add_border(image)
                        # image.save('/media/977GB/wcj_work/投标文件生成/团队生成.png')
                        # 保存图片到临时文件
                        temp_image_path = 'temp_image.png'
                        image.save(temp_image_path, 'JPEG')

                        # 将图片添加到Word文档
                        # doc.add_picture(temp_image_path, width=Inches(6))  # 设置插入的图片大小为6英寸
                        # 在文档中添加一个新的段落
                        paragraph = doc.add_paragraph()

                        # 设置段落的对齐方式为居中
                        paragraph.alignment = 1  # 1代表居中对齐

                        # 创建一个运行并添加图片
                        run = paragraph.add_run()
                        run.add_picture(temp_image_path, width=Inches(6))
        T_+=1



def add_file_to_doc(doc, file_info, path_all,level,number_str):
    """添加文件到Word文档"""
    file_path = os.path.join(path_all, file_info["path"])
    file_type = file_info["path"].split('.')[-1].lower().replace(' ','')

    try:
        if file_type in ['png', 'jpg', 'jpeg']:
            title = doc.add_heading(level=level)
            run = title.add_run(f"{number_str}.{file_info['title']}")
            run.font.name = '宋体'  # 设置字体
            run._element.rPr.rFonts.set(qn('w:eastAsia'), run.font.name)
            run.font.size = Pt(16)  # 设置字体大小
            run.font.bold = True  # 设置字体加粗
            run.font.color.rgb = RGBColor(0, 0, 0)
            title.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT

            doc.add_picture(file_path, width=Inches(6.0))
            doc.add_paragraph()  # 添加换行
        elif file_type == 'pdf':
            title = doc.add_heading(level=level)
            run = title.add_run(f"{number_str}.{file_info['title']}")
            run.font.name = '宋体'  # 设置字体
            run._element.rPr.rFonts.set(qn('w:eastAsia'), run.font.name)
            run.font.size = Pt(16)  # 设置字体大小
            run.font.bold = True  # 设置字体加粗
            run.font.color.rgb = RGBColor(0, 0, 0)
            title.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT

            images = convert_from_path(file_path)
            for image in images:
                image = trim_and_add_border(image)
                temp_image_path = 'temp_image.png'
                image.save(temp_image_path, 'JPEG')

                paragraph = doc.add_paragraph()
                paragraph.alignment = 1  # 居中对齐
                run = paragraph.add_run()
                run.add_picture(temp_image_path, width=Inches(6))
    except Exception as e:
        print(f"Error processing file {file_path}: {str(e)}")

def process_directory_tree(doc, directory_tree, path_all,numbering=None,level=1):
    if numbering is None:
        numbering = []
    """递归处理目录树"""
    for idx,item in enumerate(directory_tree):
        current_numbering = numbering + [idx + 1]  # 编号从 1 开始
        number_str = ".".join(map(str, current_numbering)) + "."
        # 添加标题
        # print("item",item)

        if not item['path']:
            title =doc.add_heading(level=level)
            run = title.add_run(f"{number_str} {item['title']}")

            run.font.name = '宋体'  # 设置字体
            run._element.rPr.rFonts.set(qn('w:eastAsia'),run.font.name)
            run.font.size = Pt(16)  # 设置字体大小
            run.font.bold = True  # 设置字体加粗
            run.font.color.rgb = RGBColor(0, 0, 0)
            title.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT

            # 处理子目录
            if item['children']:
                process_directory_tree(doc, item['children'], path_all,current_numbering,level+1)

        else:
            # 处理文件

           add_file_to_doc(doc, item, path_all,level,number_str)

#图片转换

#组装为树结构字典
def files_to_tree(files):

    # 初始化树结构
    tree = {}

    # 遍历路径列表，构建树结构
    for file in files:
        # 移除路径两端的逗号，并分割成步骤列表
        steps = file.parentPath.strip(',').split(',')

        #将当前id也加入路径
        steps.append(str(file.id))

        # 递归地构建或更新树结构
        current_level = tree
        for step in steps:
            if step:  # 确保步骤不为空
                if step not in current_level:
                    current_level[step] = {'title': file.name,
                                           'path': file.file.path if file.file else '',
                                           'children': {}}


                current_level = current_level[step]['children']
    return tree

#将树结构字典转为列表
def tree_dict2list(tree):

    #更新状态和日期
    def update_parent_status(node):
        # 获取子节点字典
        children = node.get('children', {})

        # 如果没有子节点，则不更新状态
        if not children:

            # 将字段转为列表
            node['children'] = list(node['children'].values())
            return

        # 遍历所有子节点
        for child_node in children.values():
            # 递归更新子节点的状态
            update_parent_status(child_node)

        #将字段转为列表
        node['children'] = list(node['children'].values())

    #更新状态和日期
    for _, module in tree.items():
        update_parent_status(module)

    return list(tree.values())

#对数据进行排序，父节点在前，并且顺序高的在前
def sorted_catalog(path, order):

    if path:
        path_len = len(path.split(','))
    else:
        path_len = 0

    return (path_len, order)

#将查出来的文件数据转为树结构
def file2tree(files):
    if files:
        #如果有父节点信息
        if hasattr(files[0], 'parentPath'):
            # 排序
            files = sorted(files, key=lambda x : sorted_catalog(x.parentPath, x.order))

            #梳理成json树结构
            tree = files_to_tree(files)

        elif files[0].__class__._meta.db_table == 'ex_patentSoftware':
            #专利软著为二级结构，单独处理
            tree = {}
            type2id = {}
            for i, file in enumerate(files):
                if file.type not in type2id.keys():
                    type2id[file.type] = i
                    tree[i] = {"title": file.type, "path":"", "children":{}}

                tree[type2id[file.type]]['children'][i] = {"title": file.name, "path":file.file.path, "children":{}}

        else:
            #其他均为一级
            tree = {}
            for file in files:
                if file.id not in tree.keys():
                    tree[file.id] = {"title": file.name, "path": file.file.path, "children": {}}

        # 将树结构字典转为列表
        list_tree = tree_dict2list(tree)

        # with open('树结构.json', 'w') as f:
        #     json.dump(list_tree, f, ensure_ascii=False)
    else:
        list_tree = []

    return list_tree

#添加多级标题图片
def add_folder_images_to_docx(directory,doc,text_num,path_all):
    list_tree=file2tree(directory)
    process_directory_tree(doc, list_tree, path_all,[int(text_num)])


def copy_element_style(element, doc, number):
    dict_paragraph = {}
    tem = []
    # number=0
    if element.tag.endswith('p'):  # 段落
        # 提取段落中的所有文本
        dict_paragraph[number] = {}

        element_xml = etree.fromstring(element.xml)
        # p = new_doc.add_paragraph()
        e_list_tem = [el for el in doc.element.body.inner_content_elements if "tbl" not in str(el)]
        # print("e_list_tem:",len(e_list_tem))
        # print(len(doc.paragraphs))
        paragraph = doc.paragraphs[e_list_tem.index(element)]
        # 获取段前段后间距
        # p.paragraph_format.space_before = paragraph.paragraph_format.space_before
        # p.paragraph_format.space_after = paragraph.paragraph_format.space_after
        # print("段前段后：",p.paragraph_format.space_before,p.paragraph_format.space_after)
        dict_paragraph[number]['paragraph_format.space_before'] = paragraph.paragraph_format.space_before
        dict_paragraph[number]['paragraph_format.space_after'] = paragraph.paragraph_format.space_after
        # 设置首行缩进
        # p.paragraph_format.first_line_indent=paragraph.paragraph_format.first_line_indent
        dict_paragraph[number]['paragraph_format.first_line_indent'] = paragraph.paragraph_format.first_line_indent
        # 迅雷下载
        # 提取段落对齐方式
        #  <w:pPr> <w:jc w:val="center"/>
        align = element_xml.xpath('.//w:pPr/w:jc/@w:val', namespaces=namespaces)
        if align:
            alignment = WD_PARAGRAPH_ALIGNMENT.from_xml(align[0])
            # p.alignment = alignment
            dict_paragraph[number]['alignment'] = alignment
        dict_paragraph[number]["run_text"] = []
        for run in element_xml.xpath('.//w:r', namespaces=namespaces):
            # 提取run中的文本
            run_text = "".join(run.xpath('.//w:t/text()', namespaces=namespaces))

            # 检查是否有下划线属性
            underline = run.xpath('.//w:rPr/w:u/@w:val', namespaces=namespaces)
            # print(underline)

            # 如果存在下划线属性，获取其值，否则默认为None
            underline_val = underline[0] if underline and underline[0] != "none" else None
            # print("underline_val:",underline_val)
            print('run_text', run_text,underline_val)
            if not list_none(run_text) and underline_val:
                tem_ = True
                tem.append(True)
                run_text = f"({run_text.replace(' ', '')})"
            elif run_text.replace(' ','').replace('\t','').replace('\n','')=="：" and underline_val:
                tem_ = True
                tem.append(True)
                run_text =[':','()']
            elif 'XX' in str(run_text.upper()):
                print('XX in run_text')
                tem_ = True
                tem.append(True)
                text_temp = [i for i in
                             run_text.replace(' ', '').replace('\t', '').replace('\n', '').upper().split('XX') if i]

                run_text=[]
                for i in text_temp:
                    run_text.append('()')
                    run_text.append(i)
            elif list_none(run_text) and underline_val:
                if not run_text.replace(' ', '').replace('。', '').replace(":", ''):
                    tem_ = True
                    tem.append(True)
                    run_text = f"({run_text.replace(' ', '').replace('。', '')})"
                else:
                    tem_ = False
            #         tem.append(False)
            # elif 'XX' in str(run_text.upper()):
            #     print('XX in run_text')
            #     tem_ = True
            #     tem.append(True)
            #     run_text = run_text.upper().replace('XX', '()')
            else:
                tem_ = False
                tem.append(False)
            print(tem_)
            print('run_text1:', run_text)
            if isinstance(run_text,list):
                for _i in run_text:
                    dict_paragraph[number]["run_text"].append(_i)
                    dict_paragraph[number][_i] = {}
                    dict_paragraph[number][_i]['general'] = tem_
            else:
                dict_paragraph[number]["run_text"].append(run_text)
                dict_paragraph[number][run_text] = {}

                dict_paragraph[number][run_text]['general'] = tem_

            # 如果underline_val不为None，则设置下划线
            if underline_val is not None and str(underline_val) is not "none":
                # 在docx中，underline可以是True、False或者下划线类型的字符串
                # 例如 'single', 'double', 'thick', 'dotted' 等
                # 这里将underline_val直接作为参数传递，假设它是一个有效的下划线类型
                underline_enum = getattr(WD_UNDERLINE, underline_val.upper(), None)
                # r.underline = underline_enum
                if isinstance(run_text, list):
                    for _i in run_text:
                        dict_paragraph[number][_i]['underline'] = underline_enum
                else:
                    dict_paragraph[number][run_text]['underline'] = underline_enum
                # print("r.underline",run_text,r.underline)

            # dict_paragraph[number]["run_text"].append(run_text)
            # 提取并应用字体样式
            # print("提取并应用字体样式:", run.xpath('.//w:rPr/w:rFonts/@w:ascii', namespaces=namespaces))
            if run.xpath('.//w:rPr/w:rFonts/@w:ascii', namespaces=namespaces):
                # r.font.name = run.xpath('.//w:rPr/w:rFonts/@w:ascii', namespaces=namespaces)[0]
                # r._element.rPr.rFonts.set(qn('w:eastAsia'), r.font.name)
                if isinstance(run_text, list):
                    for _i in run_text:
                        dict_paragraph[number][_i]['font.name'] = \
                            run.xpath('.//w:rPr/w:rFonts/@w:ascii', namespaces=namespaces)[0]
                else:
                    dict_paragraph[number][run_text]['font.name'] = \
                    run.xpath('.//w:rPr/w:rFonts/@w:ascii', namespaces=namespaces)[0]
            # 提取并应用字体大小
            size = run.xpath('.//w:rPr/w:sz/@w:val', namespaces=namespaces)
            if size:
                # r.font.size = Pt(int(size[0]) / 2)  # docx中的大小单位是磅，而XML中通常是半点
                if isinstance(run_text, list):
                    for _i in run_text:
                        dict_paragraph[number][_i]['font.size'] = Pt(int(size[0]) / 2)
                else:
                    dict_paragraph[number][run_text]['font.size'] = Pt(int(size[0]) / 2)
            # 提取并应用字体颜色
            color = run.xpath('.//w:rPr/w:color/@w:val', namespaces=namespaces)
            if color:
                # print("color:",color) #color=["auto"]
                if color[0].lower() == "auto":
                    # 处理 "auto" 颜色值，例如使用默认颜色或指定一个颜色
                    # 这里我们使用黑色作为示例
                    # r.font.color.rgb = RGBColor(0, 0, 0)  # 黑色的RGB值
                    if isinstance(run_text, list):
                        for _i in run_text:
                            dict_paragraph[number][_i]['font.color.rgb'] = RGBColor(0, 0, 0)
                    else:
                        dict_paragraph[number][run_text]['font.color.rgb'] = RGBColor(0, 0, 0)
                else:
                    # r.font.color.rgb = RGBColor.from_string(color[0])
                    if isinstance(run_text, list):
                        for _i in run_text:
                            dict_paragraph[number][_i]['font.color.rgb'] = RGBColor.from_string(color[0])
                    else:
                        dict_paragraph[number][run_text]['font.color.rgb'] = RGBColor.from_string(color[0])
            # dict_paragraph[number][run_text]['font.color.rgb'] = r.font.color.rgb

            # # 提取并应用加粗样式 因为有些文本有的加粗有的不加粗 这里先暂时不弄
            # bold = run.xpath('.//w:rPr/w:b', namespaces=namespaces)
            # print('黑体',bold)
            # print('文字',run_text)
            bold = run.xpath('.//w:rPr/w:b[not(@w:val="0" or @w:val="false")]', namespaces=namespaces)
            # print('黑体', bold)
            if bold:
                # print('黑体',bold)
                # r.font.bold = True
                if isinstance(run_text, list):
                    for _i in run_text:
                        dict_paragraph[number][_i]['font.bold'] = True
                else:
                    dict_paragraph[number][run_text]['font.bold'] = True

            else:
                # r.font.bold = False
                if isinstance(run_text, list):
                    for _i in run_text:
                        dict_paragraph[number][_i]['font.bold'] = False
                else:
                    dict_paragraph[number][run_text]['font.bold'] = False

            # dict_paragraph[number][run_text]['font.bold '] = r.font.bold

            for pic in run.xpath('.//w:drawing', namespaces=namespaces):
                # pic是包含图片信息的XML元素
                # 获取图片的RID
                blip = pic.xpath('.//a:blip', namespaces=namespaces)
                if blip:
                    # 假设blip是一个列表，通常情况下只有一个元素
                    blipRID = blip[0].attrib.get(qn('r:embed'))
                    # 这里可以处理blipRID，例如打印或者进行其他操作

                    # 添加图片到新文档
                    rel = doc.part.rels[blipRID]
                    image_part = doc.part.related_parts[blipRID].blob  # bytes
                    image_stream = io.BytesIO(image_part)
                    # new_doc.add_picture(image_stream, width=Inches(1.25))
        if True in tem:
            dict_paragraph[number]["general"] = True
        else:
            dict_paragraph[number]["general"] = False
        s = []
        for index_i, c_i in enumerate(dict_paragraph[number]['run_text']):
            if index_i == 0:
                s.append(c_i)
            elif index_i > 0 and dict_paragraph[number]['run_text'][index_i - 1].replace(' ', '') != c_i.replace(' ',
                                                                                                                 ''):
                s.append(c_i)
            else:
                continue
        print('s',s)
        dict_paragraph[number]['run_text'] = s
        # print('每段落的字典为：', dict_paragraph)
    elif element.tag.endswith('tbl'):  # 表格
        dict_paragraph[number] = {"table_content": []}
        # 提取表格内容
        list_d = [i for i in doc.element.body.inner_content_elements if "<w:tbl>" in str(i)]
        # print(list_d)
        table = doc.tables[list_d.index(element)]
        # 获取表格的高度信息 读不到
        # width, height = get_table_size(table)
        # print(width, height)
        # new_table = new_doc.add_table(rows=len(table.rows), cols=len(table.columns))
        table_content = []
        font_info = []
        # new_table.style = 'Table Grid'
        try:

            # 遍历原始表格的每一行和单元格
            for row_idx, row in enumerate(table.rows):
                row_content = []
                prev_value = None

                for col_idx, cell in enumerate(row.cells):
                    # 将单元格文本添加到新表格的相应单元格
                    # c_ = cell.text.strip().replace('\n', '')
                    # print('表格数据为：',c_)

                    cell_font_info = get_font_info(cell)
                    cell_text = cell_font_info['text']

                    if cell_text == prev_value:
                        c_ = ''
                        row_content.append("")
                    else:
                        c_ = cell_text
                        row_content.append(cell_text)
                        prev_value = cell_text

                    if c_:
                        dict_paragraph[number][c_] = cell_font_info
                        # print('表格样式：',c_,cell_font_info)
                    # new_table.cell(row_idx, col_idx).text = cell.text.strip()
                # print('row_content', row_content)
                table_content.append(row_content)
        except Exception as e:
            # 如果发生索引错误，打印错误信息并跳过当前行
            print(f"Error: {e} encountered while processing row ")
        # print('table_content:', table_content)
        dict_paragraph[number]["table_content"] = table_content
    return dict_paragraph

def list_none(i):
    text = i.replace(' ', '')
    if text:
        return True
    else:
        return False


def json_process(data_answ):
    pattern = r'```json(.*?)```'
    matches = re.findall(pattern, data_answ, re.DOTALL)  # 抽取出内容并判断长度
    if matches:
        c_statement = matches[-1]
        # print("\n-------step2查到的对应的内容为：\n", c_statement)
    else:
        c_statement = ''
    # decoded_object = json_repair.loads(c_statement)
    # return json.dumps(decoded_object,ensure_ascii=False)
    return c_statement


def list_obtain(text_content):
    s = []
    for index_i, c_i in enumerate(text_content):

        if index_i == 0:
            s.append(c_i)
        elif index_i > 0 and text_content[index_i - 1].replace(' ', '') != c_i.replace(' ', ''):
            s.append(c_i)
        else:
            continue
    return s


def run_r(r, run_text, content_value):
    if 'underline' in content_value[run_text]:
        r.underline = content_value[run_text]['underline']
    if 'font.name' not in content_value[run_text].keys():
        r.font.name = '宋体'
    else:
        r.font.name = content_value[run_text]['font.name']
    r._element.rPr.rFonts.set(qn('w:eastAsia'), r.font.name)
    if 'font.size' not in content_value[run_text].keys():
        r.font.size = 10.5  # 默认宋体5号字
    else:
        r.font.size = content_value[run_text]['font.size']
    r.font.color.rgb = content_value[run_text]['font.color.rgb']
    r.font.bold = content_value[run_text]['font.bold']
    return r


def split_list_by_prefix(lst, prefix):
    """
    Splits a list into three parts based on the first element that starts with the given prefix.
    :param lst: The list to be split.
    :param prefix: The prefix to look for.
    :return: A tuple of three lists: (before, prefix_element, after)
    """
    content = []
    table = []

    for item in lst:
        if isinstance(item, str) and item.startswith(prefix):
            table.append(item)

        else:
            content.append(item)

    return content, table
def add_text_with_style(doc, text):
    # 添加一个段落
    paragraph = doc.add_paragraph()

    # 设置首行缩进
    paragraph_format = paragraph.paragraph_format
    paragraph_format.first_line_indent = Pt(10.5) * 2  # 10.5号字的两字符宽度

    # 添加文本并设置样式
    run = paragraph.add_run(text)
    run.font.name = '宋体'
    run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')
    run.font.size = Pt(10.5)


def add_table_(target_doc, data_dict,table_headers,txt):
    # 初步评审响应情况

    new_table = target_doc.add_table(rows=len(data_dict[txt]) + 1, cols=len(table_headers))
    new_table.style = 'Table Grid'


    hdr_cells = new_table.rows[0].cells
    new_table.rows[0].height = Cm(1.13)
    new_table.rows[0].height_rule = WD_ROW_HEIGHT_RULE.AT_LEAST
    for i, header in enumerate(table_headers):
        hdr_cells[i].text = header
        cell_obj = new_table.cell(0, i)
        cell_obj.text = header
        # 设置单元格垂直居中对齐
        cell_obj.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
        for paragraph in cell_obj.paragraphs:
            for run in paragraph.runs:
                run.font.name = '宋体'
                run._element.rPr.rFonts.set(qn('w:eastAsia'), run.font.name)
                run.font.size = Pt(11.5)
                run.font.bold = True
                # run.font.size = Pt(content_value[text]['font_size'])
            paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER

    # 创建表格
    for row_idx, row in enumerate(data_dict[txt], start=1):
        new_table.rows[row_idx].height = Cm(1.13)
        new_table.rows[row_idx].height_rule = WD_ROW_HEIGHT_RULE.AT_LEAST
        for col_idx, col in enumerate(table_headers):
            if col in row.keys():
                text = row[col]
            else:
                if col_idx < len(list(row.keys())):
                    text = col[list(row.keys())[col_idx]]
                else:
                    text = ''

                # 设置单元格内容并居中对齐
            cell_obj = new_table.cell(row_idx, col_idx)
            cell_obj.text = text
            # 设置单元格垂直居中对齐
            cell_obj.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
            # 设置字体和大小

            for paragraph in cell_obj.paragraphs:
                for run in paragraph.runs:
                    run.font.name = '宋体'
                    run._element.rPr.rFonts.set(qn('w:eastAsia'), run.font.name)
                    run.font.size = Pt(10.5)
                    # run.font.size = Pt(content_value[text]['font_size'])
                paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
def add_text(target_doc,run_text='初步评审响应情况'):
    p = target_doc.add_paragraph()
    # run_text='初步评审响应情况'
    r = p.add_run(run_text)
    r.font.name='黑体'
    r.element.rPr.rFonts.set(qn('w:eastAsia'), r.font.name)
    r.font.size = Pt(14.5)
    r.font.color.rgb = RGBColor(0, 0, 0)
def file_t(special_file,file):
            s=[]
            for i in special_file:
                if i in file:
                    s.append(True)
                else:
                    s.append(False)
            if True in s:
                return True
            else:
                return False


def para_process(target_doc, content_value, out_general, t_num, num_key, text_num):
    p = target_doc.add_paragraph()
    if 'alignment' in content_value.keys():
        p.alignment = content_value['alignment']
    p.paragraph_format.space_before = content_value['paragraph_format.space_before']
    p.paragraph_format.space_after = content_value['paragraph_format.space_after']
    p.paragraph_format.first_line_indent = content_value['paragraph_format.first_line_indent']
    # print('content_value[run_text]', content_value['run_text'])
    if content_value['run_text']:
        for index_i, c_i in enumerate(content_value['run_text']):
            if "(" ")" in c_i and content_value['general'] and t_num < len(out_general):

                run_text = str(out_general[t_num])
                # print('run_text_new:', run_text, type(run_text))  # 检查run_text_new的值和类型
                if run_text:
                    if num_key == 1 and index_i == 0:  # 确保run_text_new非空
                        if text_num == 1:
                            r = p.add_run(f' {run_text}')
                        else:
                            r = p.add_run(f'({numbertochinese(text_num)}) {run_text}')
                    else:
                        r = p.add_run(run_text)
                    r.underline = WD_UNDERLINE.SINGLE
                    # print('keys:',content_value["()"].keys())
                    if 'font.name' in content_value["()"].keys() and content_value["()"]['font.name']:
                        r.font.name = content_value["()"]['font.name']
                    else:
                        r.font.name = '宋体'
                    r.element.rPr.rFonts.set(qn('w:eastAsia'), r.font.name)
                    if 'font.size' in content_value["()"].keys() and content_value["()"]['font.size']:
                        # print('读出来的字体大小',content_value["()"]['font.size'])
                        r.font.size = content_value["()"]['font.size']
                    # else:
                    # r.font.size = Pt(10.5)  # 设置为10.5磅
                    r.font.color.rgb = RGBColor(0, 0, 0)
                    if 'font.bold' in content_value["()"].keys() and content_value["()"]['font.bold']:
                        r.font.bold = content_value["()"]['font.bold']
                    else:
                        r.font.bold = False

                t_num += 1
            else:
                run_text = c_i
                # print('run_text:',run_text,content_value[run_text])
                if num_key == 1 and index_i == 0:  # 确保run_text_new非空
                    if text_num == 1:
                        r = p.add_run(f' {run_text}')
                    else:
                        r = p.add_run(f'({numbertochinese(text_num)}) {run_text}')
                else:
                    # r = p.add_run(run_text)
                    r = p.add_run(c_i.replace("()", ""))
                # r = p.add_run(run_text)
                if 'underline' in content_value[run_text]:
                    r.underline = content_value[run_text]['underline']
                if 'font.name' not in content_value[run_text].keys():
                    r.font.name = '宋体'
                else:
                    r.font.name = content_value[run_text]['font.name']
                r._element.rPr.rFonts.set(qn('w:eastAsia'), r.font.name)
                if 'font.size' not in content_value[run_text].keys():
                    r.font.size = Pt(10.5)  # 10.5  # 默认宋体5号字
                else:
                    r.font.size = content_value[run_text]['font.size']
                if 'font.bold' not in content_value[run_text].keys():
                    r.font.bold = False  # 10.5  # 默认宋体5号字
                else:
                    r.font.bold = content_value[run_text]['font.bold']
                r.font.color.rgb = RGBColor(0, 0, 0)
                # r.font.bold = False
    else:
        r = p.add_run('')
    return t_num
def jghsj_docx(content_value, bd, bb, target_doc,finance_prompt,config_params,file_name,task_id):
    talbe_re = content_value["table_content"]
    # print('talbe_re[0][0]', talbe_re[0][0])
    jghsjtb_dict = {}
    # print('talbe_re:',talbe_re)
    if talbe_re[0][0] and bd in talbe_re[0][0] and bb in talbe_re[0][0]:
        new_table = target_doc.add_table(rows=len(talbe_re), cols=len(talbe_re[0]))
        new_table.style = 'Table Grid'
        for row_idx, row in enumerate(talbe_re):
            s = []
            end = []
            NUM = []
            new_table.rows[row_idx].height = Cm(1.13)
            new_table.rows[row_idx].height_rule = WD_ROW_HEIGHT_RULE.AT_LEAST
            row_data = []
            for col_idx, cell in enumerate(row):
                if row_idx > 1 and row_idx < (len(talbe_re) - 1) and col_idx == 6:
                    text = 'P-P'
                    cell_obj = new_table.cell(row_idx, col_idx)
                    cell_obj.text = text
                    for paragraph in cell_obj.paragraphs:
                        for run in paragraph.runs:
                            run.font.color.rgb = RGBColor(255, 0, 0)
                            # 设置背景颜色为黄色
                    shading_elm = OxmlElement('w:shd')
                    shading_elm.set(qn('w:fill'), 'FFFF00')  # 黄色
                    cell_obj._tc.getchildren()[0].append(shading_elm)
                else:
                    text = cell.strip().replace(' ', '').replace('\n', '')

                row_data.append(text)
                if "(" ")" in text:
                    NUM.append(col_idx)
                cell_obj = new_table.cell(row_idx, col_idx)
                cell_obj.text = text
                # print('表格填充text', text)
                cell_obj.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
                if row_idx == 1:
                    for paragraph in cell_obj.paragraphs:
                        for run in paragraph.runs:
                            # print('run.text:',run.text)
                            run.font.name = '宋体'
                            run._element.rPr.rFonts.set(qn('w:eastAsia'), run.font.name)
                            run.font.size = Pt(12)
                            run.font.bold = True
                    paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
                if text:
                    s.append(col_idx)
                else:
                    end.append(col_idx)
                for paragraph in cell_obj.paragraphs:
                    # for run in paragraph.runs:
                    #     print('run.font.name:',run.font.name)
                    paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
            if len(s) and len(end):

                # print('s,end', s, end)
                if max(s) < min(end):
                    cell = new_table.cell(row_idx, max(s))
                    text = cell.text
                    # print('s,end', s, end)
                    # print(text)
                    # print('text:', text)
                    new_table.cell(row_idx, max(s)).merge(new_table.cell(row_idx, max(end)))
                    # new_table.cell(row_idx, max(s)).text=text
                    cell_obj = new_table.cell(row_idx, max(s))
                    cell_obj.text = text
                    cell_obj.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
                    if row_idx == 0:
                        for paragraph in cell.paragraphs:
                            for run in paragraph.runs:
                                run.font.name = '宋体'
                                run._element.rPr.rFonts.set(qn('w:eastAsia'), run.font.name)
                                run.font.size = Pt(12)
                                run.font.bold = True
                        paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
            s = [True for i in row_data if "(" ")" in i]
            if True in s:
                jghsjtb_dict[f'{[row_idx, NUM[-1]]}'] = row_data
    basic_info_=[]
    for key_i, value_i in jghsjtb_dict.items():
        query=f"{finance_prompt}需要填充的输入内容为：{''.join(value_i)}"
        _type = '结构化数据填报'
        t_number = 0
        global_thread_all[task_id][file_name][f"{_type}{t_number}config_params"] = deepcopy(config_params)
        global_thread_all[task_id][file_name][f"{_type}{t_number}config_params"]['messages'] = [
            {"role": "user", "content": query}]
        basic_info_.append(threading.Thread(target=dawate_streaming, args=({"type": _type, 'filename': file_name,"key_i":key_i, "t_number":t_number},)))

    for th in basic_info_:
        th.start()
    for th in basic_info_:
        threading.Thread.join(th)

    if global_thread_all[task_id][file_name]['结构化数据填报'][0]:
        for key_i,val_i in global_thread_all[task_id][file_name]['结构化数据填报'][0].items():
            key_i = list(json_repair.loads(key_i))
            # print('key_i,val_i:',key_i,val_i)
            cell_obj = new_table.cell(key_i[0], key_i[1])
            cell_text = cell_obj.text.split('()')
            # print('cell_text:', cell_text)
            text_list_ = [cell_text[0], str(val_i[0]).replace('%',''), cell_text[1]]
            # 重新填充单元格内容
            for paragraph in cell_obj.paragraphs:
                for run in paragraph.runs:
                    run.text = ''
            for i, text in enumerate(text_list_):
                if i == 1:  # 如果是中间的文本，添加下划线
                    run = cell_obj.paragraphs[0].add_run(text)
                    run.underline = True
                else:
                    cell_obj.paragraphs[0].add_run(text)
            # cell_text = cell_obj.text.replace('()',f'_{str(val_i[0])}_')
            # cell_obj.text =cell_text

# def copy_docx(source_path, target_path, file_name, dict_paragraph, file):
def copy_docx(source_path, file_name, dict_paragraph, file,table_dict_excel,pro_text,base_prompt1,
              base_prompt2, config_params, task_id):
    # 加载源文档
    global global_thread_all


    source_doc = Document(source_path)
    # 创建目标文档
    # target_doc = Document()
    # text_num = '0'
    # if int(file.split('_')[0]) > 0:
    #     text_num = int(file.split('_')[0])
    # 遍历源文档中的所有段落
    # for paragraph in source_doc.paragraphs:
    #     copy_paragraph_from_doc_to_doc(paragraph, target_doc)
    dict_paragraph[file_name] = {}
    number = 0
    from datetime import datetime

    current_time = datetime.now().strftime('%Y-%m-%d')
    # print(current_time)
    content_file_gene = []
    for element in source_doc.element.body:
        number += 1

        dict_paragraph1 = copy_element_style(element, source_doc, number)
        dict_paragraph[file_name].update(dict_paragraph1)



        # print('dict_paragraph1:',dict_paragraph1)
        if dict_paragraph1 and 'general' in dict_paragraph1[number].keys():
            if dict_paragraph1[number]['general']:
                # print(dict_paragraph1)
                # print(f"——————step1————————\n内容：{''.join(dict_paragraph1[number]['run_text'])}\n样式：{general_list}\n抽取关键信息为：")
                text_s = list_obtain(dict_paragraph1[number]['run_text']) #去除空值的
                # print('text_s:',text_s)
                if len(text_s)==1 and text_s[0]=='()':
                    last_text=''.join(dict_paragraph[file_name][number-1]['run_text'])
                    content_file_gene.append(last_text)
                # content_file_gene.append(''.join(text_s))
                for i in text_s:
                    content_file_gene.append(i)
        # text_s = ['a', ' ', 'b']
        # for i in text_s:
        #     content_file_gene.append(i)
        if dict_paragraph1 and "table_content" in dict_paragraph1[number].keys():
            table_content = dict_paragraph1[number]["table_content"]
            tem_t=False
            for i in table_content:
                for j in i:
                    if j:
                        tem_t=True

            if tem_t:
                table_content=table_content
            else:
                table_content=''
            content_file_gene.append(f'表格内容为：{table_content}')

    # print('content_file_gene:', content_file_gene)
    content, table_content = split_list_by_prefix(content_file_gene, "表格内容为")

    if table_content:
        for t_number,table_i in enumerate(table_content):
            if ''.join(table_i).replace('表格内容为：',''):

                file_key = file.replace(' ', '').split('.docx')[0]
                table_prompt=None
                for keys,values in table_dict_excel.items():
                    if keys in file:
                        table_prompt = values
                    else:
                        # print('error', file_key)
                        continue
                if table_prompt is not None:
                    table_prompt=table_prompt
                else:
                    continue

                if '直接下级控股' in str(table_i) and '直接上级控股' in str(table_i):
                    base_prompt=base_prompt1
                else:
                    base_prompt=base_prompt2
                # print('输出要求:',base_prompt)
                # answer = dify_chat_streaming(f"基本信息为：{table_prompt}，输出要求：{base_prompt}需要填充的表格内容为：{table_i}")
                query=f"基本信息为：{table_prompt}，输出要求：{base_prompt}，需要填充的表格内容为：{table_i}"
                # print('表格输入数据：',query)
                # print(query)
                # print(file_name)
                # print('\n================================\n')
                _type = '表格填充'
                global_thread_all[task_id][file_name][f"{_type}{t_number}config_params"] = deepcopy(config_params)
                global_thread_all[task_id][file_name][f"{_type}{t_number}config_params"]['messages'] = [
                    {"role": "user", "content": query}]
                global_thread_all[task_id]['basic_info_threadpool'].append(threading.Thread(target=dawate_streaming, args=({"type": _type,'number':t_number,
                                                                                                                   'filename':file_name,'task_id':task_id},)))


    if content:
        # print(f"————————step1——————————————需要填充的输入内容为：{''.join(content)}")
        # print('pro_text:',pro_text)
        # answer = dify_chat_streaming(f"{pro_text}需要填充的输入内容为：{''.join(content)}")
        query = f"{pro_text}需要填充的输入内容为：{''.join(content)},需要填写{(''.join(content)).count('()')}个括号中的内容"
        t_number=0
        # print(query)
        # print(file_name)
        # print('\n================================\n')
        _type = '文本填充'
        global_thread_all[task_id][file_name][f"{_type}{t_number}config_params"] = deepcopy(config_params)
        global_thread_all[task_id][file_name][f"{_type}{t_number}config_params"]['messages'] = [{"role": "user", "content": query}]
        global_thread_all[task_id]['basic_info_threadpool'].append(threading.Thread(target=dawate_streaming, args=({"type": _type,'number':t_number,
                                                                                                           'filename':file_name,'task_id':task_id,'content':content},)))

    return dict_paragraph
def Certificate(dict,target_doc,text_num,project_name,bidder_name,path_all):

    directory = dict['file_data']#file_data[Certificate_name]
    add_folder_images_to_docx(directory, target_doc,text_num,path_all)

def Honest_operation(dict,target_doc,text_num,project_name,bidder_name,path_all):

    directory = dict['file_data']
    add_folder_images_to_docx(directory, target_doc,text_num,path_all)


def Other_business_documents(dict,target_doc,text_num,project_name,bidder_name,path_all):


    file_name_json = './data/数据库解析内容.json'
    data_dict = extra_keyinformation_json(file_name_json)
    add_text(target_doc,run_text='1.初步评审响应情况')
    txt = '初步评审标准'
    table_headers = ['序号', '初审要素', '评审标准', '我公司响应情况']
    add_table_(target_doc, data_dict, table_headers, txt)

    add_text(target_doc,run_text='2.详细评审响应情况')
    table_headers = ['序号招标','文件条目号','简要内容描述','投标文件响应',	'偏差说明']
    new_table = target_doc.add_table(rows=1, cols=len(table_headers))
    new_table.style = 'Table Grid'
    hdr_cells = new_table.rows[0].cells
    new_table.rows[0].height = Cm(1.13)
    new_table.rows[0].height_rule = WD_ROW_HEIGHT_RULE.AT_LEAST
    for i, header in enumerate(table_headers):
        hdr_cells[i].text = header
        cell_obj = new_table.cell(0, i)
        cell_obj.text = header
        # 设置单元格垂直居中对齐
        cell_obj.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
        for paragraph in cell_obj.paragraphs:
            for run in paragraph.runs:
                run.font.name = '宋体'
                run._element.rPr.rFonts.set(qn('w:eastAsia'), run.font.name)
                run.font.size = Pt(11.5)
                run.font.bold = True
                # run.font.size = Pt(content_value[text]['font_size'])
            paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
    r = target_doc.add_page_break()
    add_sx(target_doc, '3.非联合体声明')

    p = target_doc.add_paragraph()
    r1 = p.add_run('我公司为中华人民共和国境内注册合法运作的法人，具有独立承担民事责任 的能力、独立承担招标项目的能力和独立履行合同的能力。')
    style__(r1, p)
    r2 = p.add_run('本公司保证本项目非 联合体投标。')
    r2.font.bold = True
    style__(r2, p)
    # r2.underline = True
    p.alignment = WD_ALIGN_PARAGRAPH.LEFT
    p.paragraph_format.first_line_indent = Cm(1)

    p = target_doc.add_paragraph()
    r1 = p.add_run('特此声明！')
    style__(r1, p)
    p.alignment = WD_ALIGN_PARAGRAPH.LEFT

    p = target_doc.add_paragraph()

    p = target_doc.add_paragraph()
    r1 = p.add_run('投标人名称：')
    style__(r1, p)
    r2 = p.add_run('南方电网数字平台科技（广东）有限公司')
    style__(r2, p)
    r2.underline = True
    p.alignment = WD_ALIGN_PARAGRAPH.RIGHT

    p = target_doc.add_paragraph()
    r1 = p.add_run('日期：')
    style__(r1, p)
    r2 = p.add_run('2024 ')
    style__(r2, p)
    r2.underline = True
    r3 = p.add_run('年')
    style__(r3, p)
    r4 = p.add_run('6 ')
    style__(r4, p)
    r4.underline = True
    r5 = p.add_run('月')
    style__(r5, p)
    r6 = p.add_run('10 ')
    style__(r6, p)
    r6.underline = True
    r7 = p.add_run('日')
    style__(r7, p)

    p.alignment = WD_ALIGN_PARAGRAPH.RIGHT

    r = target_doc.add_page_break()

    #
    directory  = dict['file_data']
    add_folder_images_to_docx(directory, target_doc,text_num,path_all)
def Bidders_Basic_Information(dict,target_doc,text_num,project_name,bidder_name,path_all):

    r = target_doc.add_page_break()
    directory  = dict['file_data']
    # add_folder_images_to_docx(directory, target_doc, text_num)
    add_folder_images_to_docx(directory, target_doc,text_num,path_all)
def newly_undertaken_projects(dict,target_doc,text_num,project_name,bidder_name,path_all):

    directory = dict['file_data']
    # add_folder_images_to_docx(directory, target_doc, text_num)
    # add_image_pdf(directory, target_doc)
    add_images_to_docx(directory, target_doc, text_num,path_all)
def record_honesty(dict,target_doc,text_num,project_name,bidder_name,path_all):

    r = target_doc.add_page_break()
    directory = dict['file_data']
    add_folder_images_to_docx(directory, target_doc, text_num,path_all)
    # add_image_pdf(directory, target_doc)

def record_Crimes(dict,target_doc,text_num,project_name,bidder_name,path_all):
    #无行贿犯罪记录承诺书

    r = target_doc.add_page_break()
    directory =dict['file_data']
    # add_folder_images_to_docx(directory, target_doc, text_num)
    add_folder_images_to_docx(directory, target_doc,text_num,path_all)
def Invention_patent(dict,target_doc,text_num,project_name,bidder_name,path_all):

    directory =dict['file_data']
    # add_folder_images_to_docx(directory, target_doc, text_num)
    add_folder_images_to_docx(directory, target_doc,text_num,path_all)
def Important_Information_Bidders(dict,target_doc,text_num,project_name,bidder_name,path_all):

    r = target_doc.add_page_break()
    add_sx(target_doc, '附：项目负责人相关资质证明文件')
    directory = dict['file_data']
    add_folder_images_to_docx(directory, target_doc,text_num,path_all)
def litigation_arbitration_situations(dict,target_doc,text_num,project_name,bidder_name,path_all):
    #近年发生的诉讼及仲裁情况表

    r = target_doc.add_page_break()
    add_sx(target_doc, '附：“中国裁判文书网”查询结果：')
    directory = dict['file_data']
    add_folder_images_to_docx(directory, target_doc,text_num,path_all)
def prize_award(dict,target_doc,text_num,hj_data,project_name,bidder_name,path_all):
    #获奖

    table_create(hj_data, target_doc)
    r = target_doc.add_page_break()
    directory = dict['file_data']
    add_folder_images_to_docx(directory, target_doc, text_num,path_all)
    # add_image_pdf(directory, target_doc)
def Statement_financial(dict,target_doc, text_num,project_name,bidder_name,path_all):
        #近年财务状况表



    add_sx(target_doc, '2.财务报表数据真实、完整、准确承诺函')

    p = target_doc.add_paragraph()
    r1 = p.add_run('致：')
    style__(r1, p)
    r2 = p.add_run('中国南方电网有限责任公司')
    style__(r2, p)
    r2.underline = True
    p.alignment = WD_ALIGN_PARAGRAPH.LEFT

    p = target_doc.add_paragraph()
    r1 = p.add_run('我公司正在参加')
    style__(r1, p)
    p.alignment = WD_ALIGN_PARAGRAPH.LEFT
    # r2 = p.add_run('南方电网公司2025年第一批信息化项目')
    r2 = p.add_run(bidder_name)
    style__(r2, p)
    r2.underline = True
    s = f'的投标，{bidder_name}于1995年4月成立，注册资金50000.0047万元人民币，流动资金充裕，财务状况良好，具有健全的财务会计制度，没有处于被责令停业或破产状态，且资产未被重组、接管和冻结。'
    r3 = p.add_run(s)
    style__(r3, p)
    p.paragraph_format.first_line_indent = Cm(1)

    p = target_doc.add_paragraph()
    s = '我公司已按招标文件要求提供近三年经审计的财务报告，我公司承诺：本次所提供的财务报表数据真实、完整、准确。'
    r = p.add_run(s)
    style__(r, p)
    p.paragraph_format.first_line_indent = Cm(1)

    p = target_doc.add_paragraph()
    r1 = p.add_run('审计报告详见')
    style__(r1, p)
    p.alignment = WD_ALIGN_PARAGRAPH.LEFT
    r2 = p.add_run('近三年经会计事务所审计的财务报告 P-')
    style__(r2, p)
    r2.underline = True
    p.paragraph_format.first_line_indent = Cm(1)

    p = target_doc.add_paragraph()

    p = target_doc.add_paragraph()
    r1 = p.add_run('投标人名称：')
    style__(r1, p)
    # r2 = p.add_run('南方电网数字企业科技 (广东) 有限公司')
    r2 = p.add_run(bidder_name)
    style__(r2, p)
    r2.underline = True
    p.alignment = WD_ALIGN_PARAGRAPH.RIGHT

    p = target_doc.add_paragraph()
    r = p.add_run(f"日期：{dict['file_data'][1]}")
    style__(r, p)
    p.alignment = WD_ALIGN_PARAGRAPH.RIGHT

    r = target_doc.add_page_break()

    add_sx(target_doc, '3.近三年经会计事务所审计的财务报告')

    directory = dict['file_data'][0]
    add_folder_images_to_docx(directory, target_doc,text_num,path_all)

def Query_untrustworthy(dict,target_doc, text_num,project_name,bidder_name,path_all):

    #失信情况查询结果
    add_sx(target_doc, '1.承诺函')

    p = target_doc.add_paragraph()
    r1 = p.add_run('致：')
    style__(r1, p)
    r2 = p.add_run('中国南方电网有限责任公司')
    style__(r2, p)
    r2.underline = True
    p.alignment = WD_ALIGN_PARAGRAPH.LEFT
    p = target_doc.add_paragraph()

    p = target_doc.add_paragraph()
    r1 = p.add_run('我司自愿参与贵司组织的')
    style__(r1, p)
    p.alignment = WD_ALIGN_PARAGRAPH.LEFT
    r2 = p.add_run(project_name)#('南方电网公司2025年第一批信息化项目')
    style__(r2, p)
    r2.underline = True
    r3 = p.add_run(
        '的招标活动，我司承诺我司具有健全的财务会计制度；没有处于被责令停业或破产状态， 且资产未被重组、接管和冻结；在经营活动中无重大违法失信记录；没有被国家 企业信用信息公示系统 (www.gsxt.gov.cn) 列入严重违法失信企业名单；没有 被“信用中国”网站 (www.creditchina.gov.cn) 列入失信被执行人名单；在中 国南方电网有限责任公司范围内没有处于限制投标资格的处罚期内。')
    style__(r3, p)
    p.paragraph_format.first_line_indent = Cm(1)

    p = target_doc.add_paragraph()
    p = target_doc.add_paragraph()
    r = p.add_run('特此承诺！')
    style__(r, p)
    p.alignment = WD_ALIGN_PARAGRAPH.LEFT
    p.paragraph_format.first_line_indent = Cm(1)
    p = target_doc.add_paragraph()

    p = target_doc.add_paragraph()
    r1 = p.add_run('投标人名称：')
    style__(r1, p)
    r2 = p.add_run(bidder_name)#('南方电网数字平台科技（广东）有限公司')
    style__(r2, p)
    r2.underline = True
    p.alignment = WD_ALIGN_PARAGRAPH.RIGHT

    p = target_doc.add_paragraph()
    r = p.add_run(f"日期：{dict['file_data'][1]}")
    style__(r, p)
    p.alignment = WD_ALIGN_PARAGRAPH.RIGHT

    r = target_doc.add_page_break()

    add_sx(target_doc, '2. 失信情况查询结果')

    directory = dict['file_data'][0]
    add_folder_images_to_docx(directory, target_doc,text_num,path_all)
# def add_image_pdf(directory,target_doc):
#     # target_doc = Document()
#     style = target_doc.styles.add_style('CustomHeading', 1)  # 1表示标题级别
#     font = style.font
#     font.name = '宋体'
#     style._element.rPr.rFonts.set(qn('w:eastAsia'), font.name)
#     font.size = Pt(14)
#     font.color.rgb = RGBColor(0, 0, 0)
#     font.bold = True
#     paragraph_format = style.paragraph_format
#     paragraph_format.space_after = Pt(6)
#     l_set=set()
#     for root, dirs, files in os.walk(directory):
#             for file in files:
#                 # print(os.path.join(root, file))
#                 file_path=os.path.join(root, file)
#                 tem_text=file_path.split(directory)[-1].split('\\')[:-1]
#
#                 # print(tem_text)
#                 for i in tem_text:
#                     if i and i not in l_set:
#                         target_doc.add_heading(f"{i}", level=1).style = 'CustomHeading'
#                         l_set.add(i)
#                 if file.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp')):
#                     # 图片文件路径
#                     image_path = file_path
#
#                     # 添加图片到Word文档
#                     target_doc.add_picture(image_path, width=Inches(6.0))  # 可以调整图片宽度
#
#                     # 添加一个换行符
#                     target_doc.add_paragraph()
#                 elif file.lower().endswith(('.pdf')):
#                     # print('file', file)
#                     pdf_path = file_path
#                     pdf_path = pdf_path.replace('\\', '/')
#                     # print('pdf_path', pdf_path)
#                     images = convert_from_path(pdf_path)
#                     # 遍历所有图片并将其添加到Word文档中
#                     for image in images:
#                         image = trim_and_add_border(image)
#                         # image.save('/media/977GB/wcj_work/投标文件生成/团队生成.png')
#                         # 保存图片到临时文件
#                         temp_image_path = 'temp_image.png'
#                         image.save(temp_image_path, 'JPEG')
#
#                         # 将图片添加到Word文档
#                         # doc.add_picture(temp_image_path, width=Inches(6))  # 设置插入的图片大小为6英寸
#                         # 在文档中添加一个新的段落
#                         paragraph = target_doc.add_paragraph()
#
#                         # 设置段落的对齐方式为居中
#                         paragraph.alignment = 1  # 1代表居中对齐
#
#                         # 创建一个运行并添加图片
#                         run = paragraph.add_run()
#                         run.add_picture(temp_image_path, width=Inches(6))
def style__(r,p):
    r.font.name = '宋体'
    r.element.rPr.rFonts.set(qn('w:eastAsia'), r.font.name)
    r.font.size = Pt(11.5)
    r.font.color.rgb = RGBColor(0, 0, 0)

def add_tt(target_doc,run_text):
    p = target_doc.add_paragraph()
    # run_text='初步评审响应情况'
    r = p.add_run(run_text)
    r.font.name='宋体'
    r.element.rPr.rFonts.set(qn('w:eastAsia'), r.font.name)
    r.font.size = Pt(14.5)
    r.font.color.rgb = RGBColor(0, 0, 0)
    r.font.bold = True
    p.alignment = 1 # 0为左对齐，1为居中，2为右对齐
def add_t(target_doc,run_text):
    p = target_doc.add_paragraph()
    # run_text='初步评审响应情况'
    r = p.add_run(run_text)
    r.font.name = '宋体'
    r.element.rPr.rFonts.set(qn('w:eastAsia'), r.font.name)
    r.font.size = Pt(14.5)
    r.font.color.rgb = RGBColor(0, 0, 0)
    r.font.bold = False
def add_sx(target_doc,run_text):
    p = target_doc.add_paragraph()
    # run_text='初步评审响应情况'
    r = p.add_run(run_text)
    r.font.name='宋体'
    r.element.rPr.rFonts.set(qn('w:eastAsia'), r.font.name)
    r.font.size = Pt(14.5)
    r.font.color.rgb = RGBColor(0, 0, 0)
    r.font.bold=True
def excel_(df,bib_name):
    for row in range(df.shape[0]):
        for col in range(df.shape[1]):
            s = str(df.iloc[0, col])
            if bib_name in s:
                return True
            else:
                return False

def extra_keyinformation_json(file_name_json):
    import json
    # 假设我们有一个名为"data.json"的JSON文件
    # file_name_json = './data/数据库解析内容.json'

    # 使用open函数打开文件，并使用json.load()将内容加载为字典
    with open(file_name_json, 'r', encoding='utf-8') as file:
        data_dict = json.load(file)

    # 现在data_dict就是一个Python字典，包含了JSON文件中的数据
    # print(data_dict['基础信息']['招标人/代理人基本信息'])
    return data_dict
def add_jghsj_(target_doc,excel_file,text_num,bib_name):
    # 遍历所有sheets
    for sheet_name in excel_file.sheet_names:
        # 读取每个sheet到DataFrame，不包括表头
        df = pd.read_excel(excel_file, sheet_name=sheet_name, header=None)

        if sheet_name=="封面":
            for row in range(df.shape[0]):
                for col in range(df.shape[1]):
                    text = str(df.iloc[row, col]).strip().replace(' ','')
                    text_list=text.split('\n')
                    for index,i in enumerate(text_list):
                        if index==0:
                            add_tt(target_doc, f'({text_num}) {i}')
                        elif i:
                            add_t(target_doc, i)

        else:
            # 在Word文档中添加一个表格，行数和列数与DataFrame相同
            if excel_(df,bib_name):
                new_table = target_doc.add_table(rows=df.shape[0], cols=df.shape[1])
                new_table.style = 'Table Grid'

                # 填充表格数据
                # print('df.shape[0]',df.shape[0])
                for row in range(df.shape[0]):
                    # print('row',row)
                    s = []
                    end = []
                    new_table.rows[row].height = Cm(1.13)
                    new_table.rows[row].height_rule = WD_ROW_HEIGHT_RULE.AT_LEAST
                    for col in range(df.shape[1]):

                        cell = new_table.cell(row, col)
                        if row>1 and row<(df.shape[0]-1) and col==6:
                            cell.text ='P-P'
                            # # 高亮黄色
                            # for paragraph in cell.paragraphs:
                            #     for run in paragraph.runs:
                            #         run.font.highlight_color = WD_COLOR.YELLOW

                        else:
                            cell.text = str(df.iloc[row, col]).strip().replace(' ', '').replace('nan','')
                        # print(col,cell.text)
                        cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
                        if row==1:
                            for paragraph in cell.paragraphs:
                                for run in paragraph.runs:
                                    run.font.name = '宋体'
                                    run._element.rPr.rFonts.set(qn('w:eastAsia'), run.font.name)
                                    run.font.size = Pt(12)
                                    run.font.bold = True
                            paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER

                        if cell.text:
                            s.append(col)
                        else:
                            end.append(col)
                        for paragraph in cell.paragraphs:
                            # for run in paragraph.runs:
                            #     print('run.font.name:',run.font.name)
                            paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
                    if s and end:
                        # print('s,end', s, end)
                        cell = new_table.cell(row,max(s))
                        text=cell.text
                        # print('text:', text)
                        new_table.cell(row, max(s)).merge(new_table.cell(row, max(end)))
                        # new_table.cell(row_idx, max(s)).text=text
                        cell_obj = new_table.cell(row, max(s))
                        cell_obj.text = text
                        cell_obj.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
                        if row==0:
                            for paragraph in cell.paragraphs:
                                for run in paragraph.runs:
                                    run.font.name = '宋体'
                                    run._element.rPr.rFonts.set(qn('w:eastAsia'), run.font.name)
                                    run.font.size = Pt(12)
                                    run.font.bold = True
                            paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER

            else:
                continue
def write_xlsx(source_path, target_path, file,bib_name):
    excel_file = pd.ExcelFile(source_path)
    # 创建目标文档
    target_doc = Document()
    text_num = file.split('_')[0]
    text_num = numbertochinese(text_num)
    add_jghsj_(target_doc, excel_file,text_num,bib_name)
    target_doc.save(target_path)
def numbertochinese(numstr):
    numstr = str(numstr)

    # 中文数字映射
    chinesenumbers = {
        '0': '零',
        '1': '一',
        '2': '二',
        '3': '三',
        '4': '四',
        '5': '五',
        '6': '六',
        '7': '七',
        '8': '八',
        '9': '九'
    }

    # 单位
    units = ['', '十', '百', '千', '万']

    # 如果数字是0，直接返回'零'
    if int(numstr) == 0:
        return '零'

    result = ''
    length = len(numstr)

    for i, digit in enumerate(numstr):
        # 当前数字的中文表示
        chinesedigit = chinesenumbers[digit]

        # 当前数字的单位
        unit = units[length - i - 1]

        # 处理连续的零
        if digit == '0':
            if result and result[-1] != '零':
                result += '零'
        else:
            result += chinesedigit + unit

    # 去除末尾的零
    result = result.rstrip('零')

    # 处理十位上的零，例如"一百零十"应该为"一百一十"
    if result.startswith('一十'):
        result = result[1:]

    return result

#将django查询结果转为字典
def model_to_dict(instance):
    if instance is None:
        return None

    # 获取模型的字段
    fields = instance._meta.fields

    # 创建一个字典来存储字段值
    data = {}

    for field in fields:
        # 获取字段的名称和值
        field_name = field.name
        field_value = getattr(instance, field_name)

        # 如果字段值是外键，获取其 ID
        if field.get_internal_type() == 'ForeignKey':
            field_value = field_value.id if field_value else None

        # 将字段名称和值添加到字典中
        if not field_value:
            field_value = '无'

        data[field_name] = field_value

    return data

#计算年龄
def calculate_age(birthday):
    today = date.today()
    age = today.year - birthday.year

    # 如果当前日期的月份和日期早于出生日期的月份和日期，则年龄减1
    if (today.month, today.day) < (birthday.month, birthday.day):
        age -= 1

    return age

# 将整数转换为中文数字
def number_to_chinese(num):
    """
    将整数转换为中文数字（支持最大值：999,999,999）
    """
    digits = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']
    places = ['', '十', '百', '千']
    units = ['', '万', '亿', '兆']

    if num == 0:
        return '零'

    result = ''
    str_num = str(num)[::-1]  # 从右往左处理
    length = len(str_num)

    for i in range(0, length, 4):
        chunk = str_num[i:i+4][::-1]  # 每四位一组，正序处理
        unit_index = i // 4
        chunk_result = ''

        chunk_length = len(chunk)
        prev_zero = False

        for j in range(chunk_length):
            digit = int(chunk[j])
            pos = chunk_length - j - 1

            if digit == 0:
                prev_zero = True
                if chunk_result[-1:] != '零' and (j < chunk_length - 1):
                    chunk_result += '零'
                continue

            if prev_zero and chunk_result:
                chunk_result = chunk_result[:-1]  # 去掉前面多余的“零”
                prev_zero = False

            if pos > 0:
                chunk_result += digits[digit] + places[pos]
            else:
                chunk_result += digits[digit]

        if chunk_result and chunk_result[-1] == '零':
            chunk_result = chunk_result[:-1]

        if chunk_result:
            chunk_result += units[unit_index]
        result = chunk_result + result

    # 处理特殊情况
    if result.startswith('一十'):
        result = result[1:]

    return result

#修改docx内容的编号
def modify_docx_number(num, source_path, generate_path, first_para=None):

    doc = Document(source_path)

    for para in doc.paragraphs:

        for run in para.runs:
            text = run.text
            print(text)
            if text.startswith('（九十九'):
                run.text = text.replace('九十九',f'{number_to_chinese(num)}')
            elif para.text.startswith('99.'):
                run.text = text.replace('99.', f'{num}.')

    #如果需要替换第二段
    if first_para is not None:
        try:
            first_paragraph = doc.paragraphs[1]
            first_paragraph.clear()
            run = first_paragraph.add_run(first_para)
            # print([doc.paragraphs[1].text])
            run.bold = False
            run.font.size = Pt(14)
            # 设置字体为宋体
            run.font.name = 'SimSun'  # 英文名'SimSun'对应宋体
            run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')  # 确保中文字符使用宋体
            first_paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT
            first_paragraph.paragraph_format.line_spacing = 1.5  # 设置行间距为1.5倍
            first_paragraph.paragraph_format.first_line_indent = Pt(24)  # 设置首行缩进为2个字符（大约24磅）
            first_paragraph.paragraph_format.space_before = Pt(13)  # 设置段前间距为13磅
        except:
            pass

    # print([doc.paragraphs[1].text])

    doc.save(generate_path)

    #原来的文件也用新文件替换掉
    # doc.save(source_path)
def write_content(dict_paragraph,target_doc,text_num,target_path,file_name,special_file,path_all,function_data,IDCard,
                  hj_data,project_name,bidder_name,targetname_,bidd_package_,config_params,finance_prompt,task_id,source_path):
    t_num = 0
    table_num = 0
    # print(dict_paragraph)
    test_num = 0

    for num_key, content_value in dict_paragraph[file_name].items():
        # print('global_thread_all[task_id][file_name]',global_thread_all[task_id][file_name])
        if "table_content" in content_value.keys():
            if '结构化数据填报' in file_name:

                bd = targetname_.strip().replace(' ','')
                bb = bidd_package_.strip().replace(' ','')
                jghsj_docx(content_value, bd, bb, target_doc,finance_prompt,config_params,file_name, task_id)
            else:
                # print(global_thread)
                if global_thread_all[task_id][file_name]['表格填充'][0]:
                    # row_height = Cm(1.13)

                    # 临时跳过去
                    if table_num not in global_thread_all[task_id][file_name]['表格填充'][0].keys():
                        continue

                    talbe_re = global_thread_all[task_id][file_name]['表格填充'][0][table_num]
                    if '投标偏差表' in file_name:
                        talbe_re=[["序号", "标文件章节及条款号", "投标文件章节及条款号", '偏差说明', '对应投标文件页码'],
                                        ['1', '招标文件所有章节及条款号', '投标文件所有章及条款号', '无偏差', '详见整份投标文件']]

                    # print('带填充的表格数据',talbe_re)
                    # print('类型为：',type(talbe_re))
                    if not talbe_re:
                        continue
                    new_table = target_doc.add_table(rows=len(talbe_re), cols=len(talbe_re[0]))
                    new_table.style = 'Table Grid'
                    try:
                        # 创建表格

                        for row_idx, row in enumerate(talbe_re):
                            s = []
                            end = []
                            new_table.rows[row_idx].height = Cm(1.13)
                            new_table.rows[row_idx].height_rule = WD_ROW_HEIGHT_RULE.AT_LEAST
                            for col_idx, cell in enumerate(row):
                                # 将单元格文本添加到新表格的相应单元格
                                text = str(cell).strip().replace(' ', '').replace('\n', '')
                                if text:
                                    s.append(col_idx)
                                else:
                                    end.append(col_idx)
                                    # 设置单元格内容并居中对齐
                                cell_obj = new_table.cell(row_idx, col_idx)
                                cell_obj.text = text
                                # 设置单元格垂直居中对齐
                                cell_obj.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
                                # 设置字体和大小
                                if text in content_value.keys():
                                    for paragraph in cell_obj.paragraphs:
                                        for run in paragraph.runs:
                                            if content_value[text]['font_name']:
                                                run.font.name = content_value[text]['font_name']
                                            else:
                                                run.font.name = '宋体'
                                            run._element.rPr.rFonts.set(qn('w:eastAsia'), run.font.name)
                                            if content_value[text]['font_size']:
                                                run.font.size = Pt(content_value[text]['font_size'])
                                            else:
                                                run.font.size = Pt(10.5)
                                            # run.font.size = Pt(content_value[text]['font_size'])
                                            run.font.bold = content_value[text]['bold']
                                            if content_value[text]['italic']:
                                                run.font.italic = content_value[text]['italic']
                                            if content_value[text]['underline']:
                                                run.underline = content_value[text]['underline']
                                        paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
                                else:
                                    for paragraph in cell_obj.paragraphs:
                                        for run in paragraph.runs:
                                            run.font.name = "宋体"
                                            run._element.rPr.rFonts.set(qn('w:eastAsia'), "宋体")
                                            run.font.size = Pt(10.5)
                                        paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
                                    # new_table.cell(row_idx, col_idx).text = text
                            if s and end:
                                # print('s,end', s, end)
                                text = talbe_re[row_idx][max(s)]
                                # print('text:', text)
                                new_table.cell(row_idx, max(s)).merge(new_table.cell(row_idx, max(end)))
                                # new_table.cell(row_idx, max(s)).text=text
                                cell_obj = new_table.cell(row_idx, max(s))
                                cell_obj.text = text
                                cell_obj.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
                                if text in content_value.keys():
                                    for paragraph in cell_obj.paragraphs:
                                        for run in paragraph.runs:
                                            if content_value[text]['font_name']:
                                                run.font.name = content_value[text]['font_name']
                                            else:
                                                run.font.name = '宋体'
                                            run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')
                                            if content_value[text]['font_size']:
                                                run.font.size = Pt(content_value[text]['font_size'])
                                            else:
                                                run.font.size = Pt(10.5)
                                            run.font.bold = content_value[text]['bold']
                                            if content_value[text]['italic']:
                                                run.font.italic = content_value[text]['italic']
                                            if content_value[text]['underline']:
                                                run.underline = content_value[text]['underline']
                                        # paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER

                                else:
                                    for paragraph in cell_obj.paragraphs:
                                        for run in paragraph.runs:
                                            run.font.name = "宋体"
                                            run._element.rPr.rFonts.set(qn('w:eastAsia'), "宋体")
                                            run.font.size = Pt(10.5)
                                        paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
                            # print('s,end',s,end)
                            elif not s and end[0] == 0 and len(end) == len(talbe_re[0]):
                                new_table.cell(row_idx, 0).merge(new_table.cell(row_idx, max(end)))
                                cell_obj = new_table.cell(row_idx, max(end))
                                cell_obj.text = ''

                    except Exception as e:
                        # 如果发生索引错误，打印错误信息并跳过当前行
                        print(f"Error: {e} encountered while processing row ")

                    table_num += 1
                else:
                    talbe_re = content_value["table_content"]
                    new_table = target_doc.add_table(rows=len(talbe_re), cols=len(talbe_re[0]))
                    # new_table.style = 'Table Grid'

                    # 创建表格
                    for row_idx, row in enumerate(talbe_re):

                        new_table.rows[row_idx].height = Cm(1.13)
                        new_table.rows[row_idx].height_rule = WD_ROW_HEIGHT_RULE.AT_LEAST
                        for col_idx, cell in enumerate(row):
                            text = cell.strip().replace(' ', '').replace('\n', '')
                            cell_obj = new_table.cell(row_idx, col_idx)
                            cell_obj.text = text
                        if '法定代表人（单位负责人）身份证明' in file_name:
                            cell_image = new_table.cell(0, 0)
                            paragraph = cell_image.add_paragraph()
                            run = paragraph.add_run()
                            run.add_picture(os.path.join(path_all, IDCard[0]), width=Inches(3.0))  # 设置图片路径和宽度
                            paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER

                            cell_image = new_table.cell(0, 1)
                            paragraph = cell_image.add_paragraph()
                            run = paragraph.add_run()
                            run.add_picture(os.path.join(path_all, IDCard[1]), width=Inches(3.0))  # 设置图片路径和宽度
                            paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER

                        if '授权委托书' in file_name:

                            if test_num == 0:
                                cell_image = new_table.cell(0, 0)
                                paragraph = cell_image.add_paragraph()
                                run = paragraph.add_run()
                                run.add_picture(os.path.join(path_all, IDCard[0]), width=Inches(3.0))  # 设置图片路径和宽度
                                paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER

                                cell_image = new_table.cell(0, 1)
                                paragraph = cell_image.add_paragraph()
                                run = paragraph.add_run()
                                run.add_picture(os.path.join(path_all, IDCard[1]), width=Inches(3.0))  # 设置图片路径和宽度
                                paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
                                test_num += 1
                            elif test_num == 1:
                                cell_image = new_table.cell(0, 0)
                                paragraph = cell_image.add_paragraph()
                                run = paragraph.add_run()
                                run.add_picture(os.path.join(path_all, IDCard[2]), width=Inches(3.0))  # 设置图片路径和宽度
                                paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER

                                cell_image = new_table.cell(0, 1)
                                paragraph = cell_image.add_paragraph()
                                run = paragraph.add_run()
                                run.add_picture(os.path.join(path_all, IDCard[3]), width=Inches(3.0))  # 设置图片路径和宽度
                                paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER

        else:
            # if num_key==1:
            # print('content_value[run_text]',content_value['run_text'])
            # content_value['run_text']=[f'{text_num}{i}' if index==0 else i for index,i in enumerate(content_value['run_text'])]
            if file_t(special_file, file_name):
                if num_key == 1:
                    t_num = para_process(target_doc, content_value, global_thread_all[task_id][file_name]['文本填充'], t_num, num_key, text_num)
                else:
                    continue
            else:
                t_num = para_process(target_doc, content_value, global_thread_all[task_id][file_name]['文本填充'], t_num, num_key, text_num)

    # print(file_name, target_path)
    for dict in function_data:
        Certificate_name = dict['file_name']
        Analytical_function = dict['Analytical function']
        if Certificate_name in file_name:
            if '获奖' in file_name:
                Analytical_function(dict, target_doc, text_num, hj_data, project_name, bidder_name, path_all)
            else:
                Analytical_function(dict, target_doc, text_num, project_name, bidder_name, path_all)

    if '商务响应' in file_name:
        text = "应答：我公司承诺质保期满足技术规范书要求，完全响应招标文件和合同要求，详见投标文件全文。"
        add_text_with_style(target_doc, text)

    # text_num = file.split('_')[0]

    #     print('段落结果：',p)
    # number=0
    # for element in source_doc.element.body:
    #     number += 1
    #     dict_paragraph1=copy_element_style_general(element,source_doc,target_doc,number)

    if not global_thread_all[task_id][file_name]['文本填充'] and not global_thread_all[task_id][file_name]['表格填充'][0] \
        and not global_thread_all[task_id][file_name]['结构化数据填报'][0] and '法定代表人（单位负责人）身份证明' not in file_name \
            and '授权委托书' not in file_name:
        copyfile(source_path, target_path)
    else:
        target_doc.save(target_path)

#其他文件编号
def generate_numbered_document(docxpath, outputpath, start_number):
    document = Document(docxpath)


    # 用于跟踪当前标题的层级和编号
    level_stack = [start_number]  # 从指定的起始数字开始

    for paragraph in document.paragraphs:
        style = paragraph.style.name
        text = paragraph.text.strip()

        if style.startswith('Heading'):
            # 提取标题级别 (Heading 1 -> 1, Heading 2 -> 2, etc.)
            level = int(style.split()[-1])

            # 更新编号栈
            while len(level_stack) > level:
                level_stack.pop()  # 回退到当前级别

            if len(level_stack) < level:
                # 进入新级别，初始化编号
                level_stack.append(1)
            else:
                # 同级别标题，增加编号
                level_stack[level - 1] += 1
                # 重置所有次级编号为1
                for i in range(level, len(level_stack)):
                    level_stack[i] = 1

            # 生成完整的编号字符串
            number = '.'.join(map(str, level_stack[:level]))
            fulltext = f"{number} {text}"
        else:
            continue
        paragraph.text=fulltext

    document.save(outputpath)

def business_generate(catalogs, _id, account, config_params,task_id):
    company_ExBid = ExBid.objects.filter(id=_id).select_related('pmProject', 'project', 'bidParse', 'target', 'package').first()
    project_name = company_ExBid.projectName
    targetname_=company_ExBid.target.name #标的名称
    bidd_package_=company_ExBid.package.name #标包名称
    # 获取公司名称
    company = ExTeam.objects.filter(account=account).select_related('company').first().company
    bidder_name = company.name
    # print('bidder_name:', bidder_name)
    company_qualification = ExQualification.objects.filter(company=company.id).distinct()
    certificates = list(company_qualification)

    # ex_qualification 公司证书
    company_qualification = ExQualification.objects.filter(company=company.id).select_related('file').distinct()

    # ex_integritymanage,诚信经营
    company_integritymanage = ExIntegrityManage.objects.filter(company=company.id).select_related('file').distinct()
    company_integritymanage_content=[model_to_dict(c_i) for c_i in company_integritymanage]
    # 投标人基本情况表
    company_BasicInfo = ExBasicInfo.objects.filter(company=company.id).select_related('file').distinct()
    # for i in company_BasicInfo:
    #     print(i)
    #     print('i.file.path:',i.file.path)
    # 正在履行和新承接的项目
    Doing_project = ExProject.objects.filter(company=company.id, acceptanceDate=None).select_related('winBid',
                                                                                                     'contractScan',
                                                                                                     'contractTransfer',
                                                                                                     'acceptanceCert',
                                                                                                     'invoice',
                                                                                                     'companyChange').distinct()
    Doing_project_comments = {
        field.name: field.help_text
        for field in ExProject._meta.get_fields()
        if hasattr(field, 'help_text')
    }

    # ExIntegrityIncorrupt 诚信和廉洁方面无不良记录的证明材料
    company_IntegrityIncorrupt = ExIntegrityIncorrupt.objects.filter(company=company.id).select_related(
        'file').distinct()
    # 无行贿犯罪记录承诺书
    company_Bribery = ExBribery.objects.filter(company=company.id).select_related('file').distinct()
    # 发明或专利 ExPatentSoftware
    company_PatentSoftware = ExPatentSoftware.objects.filter(company=company.id).select_related('file').distinct()

    # 投标人重要信息情况表

    # 从数据库获取项目负责人
    query = Q(bid=_id, position='项目负责人')
    bidPM = ExBidTeam.objects.filter(query).select_related('bid', 'account').distinct().first()

    # ex_teamqualification 项目负责人证书
    bidPM_Qualification = ExTeamQualification.objects.filter(account=bidPM.account.account).select_related(
        'file').distinct()

    # 近年发生的诉讼及仲裁情况表
    company_suitArbitrate = ExLawsuitArbitrate.objects.filter(company=company.id).distinct()

    company_suitArbitrateResult = ExLawsuitArbitrateResult.objects.filter(company=company.id).select_related(
        'file').distinct()

    # ex_award 公司获奖信息表 ExQualification
    company_ExAward = ExAward.objects.filter(company=company.id).select_related('company').select_related(
        'file').distinct()
    #奖项  15个（国家级科学技术奖励1个、省部级科学技术奖励3个、行业协会科学技术奖励11个）奖项
    # 统计基于 prize 和 level 的奖状数量
    award_counts = company_ExAward.values('prize', 'level').annotate(count=Count('id'))

    # 打印结果
    Prize_c=[]
    for award in award_counts:
        Prize_c.append(f"{award['level']}{award['prize']}{award['count']}个")

    # 近年财务状况表
    company_ExFinanceAudits = ExFinanceAudits.objects.filter(company=company.id).select_related('company').distinct()
    # 失信情况查询结果
    company_ExPromise = ExPromise.objects.filter(company=company.id).select_related('company').select_related(
        'file').distinct()

    # 转换开标日期
    date_format = company_ExBid.bidOpenTime.strftime("%Y年%m月%d日")

    function_data = [{'file_name': '证书', 'file_data': company_qualification, 'Analytical function': Certificate},
                     {'file_name': '诚信经营', 'file_data': company_integritymanage, 'Analytical function': Certificate},
                     {'file_name': '信用评价', 'file_data': company_integritymanage, 'Analytical function': Certificate},
                     {'file_name': '投标人基本情况表', 'file_data': company_BasicInfo,
                      'Analytical function': Bidders_Basic_Information},
                     {'file_name': '正在履行和新承接的项目', 'file_data': [Doing_project, Doing_project_comments],
                      'Analytical function': newly_undertaken_projects},
                     {'file_name': '诚信和廉洁方面无不良记录', 'file_data': company_IntegrityIncorrupt,
                      'Analytical function': Bidders_Basic_Information},
                     {'file_name': '无行贿犯罪记录承诺书', 'file_data': company_Bribery,
                      'Analytical function': Bidders_Basic_Information},
                     {'file_name': '发明或专利', 'file_data': company_PatentSoftware, 'Analytical function': Certificate},
                     {'file_name': '投标人重要信息情况表', 'file_data': bidPM_Qualification,
                      'Analytical function': Important_Information_Bidders},
                     {'file_name': '近年发生的诉讼及仲裁情况表', 'file_data': company_suitArbitrateResult,
                      'Analytical function': litigation_arbitration_situations},
                     {'file_name': '获奖', 'file_data': company_ExAward, 'Analytical function': prize_award},
                     {'file_name': '近年财务状况表', 'file_data': [company_ExFinanceAudits, date_format],
                      'Analytical function': Statement_financial},
                     {'file_name': '失信情况查询结果', 'file_data': [company_ExPromise, date_format],
                      'Analytical function': Query_untrustworthy},

                     ]
    company_agent = ExLegalAgents.objects.filter(account=company_ExBid.agent.account).first()

    special_file = ['证书', '诚信经营', '商务响应', '需要提供的其他商务文件', '失信情况查询结果']

    base_prompt1 = '''
                     将待填充的表格数据补充完整，并且按照行以list的形式输出表格内容,保证都是正确的json格式双引号，如果有表头记得带上表头
                     输出的时候在直接上级控股和直接下级控股两个表格之间添加一个空行["","",""...],再把两个表放在一个表中，
                     如果不存在上级或下级企业，则依旧需要输出表头和内容，并在每个内容单元格中填写无
                     输出样例：
                     ```json
                   [["直接上级控股/管理单位/自然人控股股东名称", "对本单位的控股（出资）比例（%）", "单位负责人", "联系人及电话", "单位地址"],
                    ["xxxxx", xxxx, "xxx", "xxx", "xxxx"],
                    ["", "", "", "", ""],
                    ["直接下级控股/管理单位名称", "本单位控股（出资）比例（%）", "单位负责人", "联系人及电话", "单位地址"],
                    ["无", "无", "无", "无", "无"]]
                    ```
                     '''
    base_prompt2 = '''
                                     将待填充的表格数据补充完整，并且按照行输出表格内容,保证都是正确的json格式双引号，如果有表头记得带上表头，不要删除表头及字段,如果存在空行，不要输出,如果存在需要填内容但是没内容，那请填写无，原本就是空不需要填写内容就返回空""
                                     输出样例：
                                            ```json
                                           [["投标人名称", "xxx", "曾用名", "xxx"],
                                            ["企业性质", "xxx", "注册地址", "xxx"]]
                                           '''
    # 7 投标人重要信息情况表
    tbrzyxx_data = '''
                                  [['项目', '南方电网公司2025年第一批信息化项目', '', '', '', ''],
                                   ['标的', '标的2：数字化技术平台2025年第一批采购项目', '', '', '', ''], 
                                   ['标包', '标包5：移动应用平台V3.1（质量评价分析及安全提升）建设项目', '', '', '', ''], 
                                   ['序号', '投标人名称', '质量', '服务期/交货期', '项目负责人姓名', '项目负责人相关证书名称及编号'], 
                                   ['1', '南方电网数字平台科技（广东）有限公司', '完全满足招标文件要求', '自合同签订之日起12个月内完成项目竣工验收。', 
                                   '刘兆平', '高级工程师；系统分析师：15102440008']]
                                  '''
    # 8 关联企业
    company_ExAffiliates = ExAffiliates.objects.filter(company=company.id).select_related('company').distinct()
    type_ = [c_i.type for c_i in company_ExAffiliates]
    must_l = ['上级', '下级', '兄弟']
    must_l_content = []
    for i in must_l:
        if i not in type_:
            t_ = f"['直接{i}控股/管理单位名称', '本单位控股（出资）比例（%）', '单位负责人', '联系人及电话', '单位地址'], ['无', '', '', '', '']]"
            must_l_content.append(t_)
    company_ExAffiliates_content = [model_to_dict(c_i) for c_i in company_ExAffiliates]
    # 获取字段备注
    field_comments = {
        field.name: field.help_text
        for field in ExAffiliates._meta.get_fields()
        if hasattr(field, 'help_text')
    }
    # for field_name, comment in field_comments.items():
    #     print(f"字段: {field_name}, 备注: {comment}")
    glqy_data = f'关联企业情况表：{company_ExAffiliates_content},{must_l_content}表字段说明:{field_comments}'

    # 9 jncwzk
    company_ExFinance = ExFinance.objects.filter(company=company.id).select_related('company').distinct()
    # 获取字段备注
    field_comments = {
        field.name: field.help_text
        for field in ExFinance._meta.get_fields()
        if hasattr(field, 'help_text')
    }
    result = company_ExFinance.aggregate(
        avg_total_assets=Avg('totalAssets'),
        avg_net_assets=Avg('netAssets'),
        avg_current_assets=Avg('currentAssets'),
        avg_total_liabilities=Avg('totalLiabilities'),
        avg_current_liabilities=Avg('currentLiabilities'),
        avg_current_liabilities1=Avg('operatingIncome'),
        avg_current_liabilities2=Avg('netProfit'),
        avg_current_liabilities3=Avg('operatingNetProfitMargin'),
        avg_current_liabilities4=Avg('netCashFlow'),
        avg_current_liabilities5=Avg('netCashFlowRatio'),
        avg_current_liabilities6=Avg('totalProfit')
    )
    company_ExFinance_contnt = [model_to_dict(c_i) for c_i in company_ExFinance]
    jncwzk_data = f'近年财务状况:{company_ExFinance_contnt},平均值为：{result},表中字段说明为：{field_comments}'

    tbpcb_prompt3 = '''投标偏差表: ["投标偏差表（商务部分）：[["序号", "标文件章节及条款号", "投标文件章节及条款号", '偏差说明', '对应投标文件页码'],['1', '招标文件所有章节及条款号', '投标文件所有章及条款号', '无偏差', '详见整份投标文件']]"]
                                                  '''
    # 投标人基本情况表
    ExCompany_data = ExCompany.objects.filter(id=company.id).distinct()
    ExCompany_data_name = [model_to_dict(c_i) for c_i in ExCompany_data]
    # 获取字段备注
    ExCompany_data_name_comments = {
        field.name: field.help_text
        for field in ExCompany._meta.get_fields()
        if hasattr(field, 'help_text')
    }

    company_qualification_name = [c_i.name for c_i in company_qualification]
    legal_person = ExLegalAgents.objects.filter(company=company.id, type='法人').select_related('IDCardFront',
                                                                                              'IDCardBack').first()
    # print('id', company.id)
    # print('法人：', legal_person.name)
    legal_person_dict = model_to_dict(legal_person)

    tbrjbqk_data = f'投标人基本情况表为:{ExCompany_data_name}。表中字段说明为：{ExCompany_data_name_comments}' \
                   f'公司法定代表人信息为：{legal_person_dict},' \
                   f'委托代理人基本信息(联系人):{model_to_dict(company_agent)},' \
                   f'公司证书{company_qualification_name}'

    pro_text = f''' 项目基本信息为：
                项目名称为：{project_name}，"标的名称": {targetname_}, "标包名称":{bidd_package_}，投标日期'： {company_ExBid.bidOpenTime},投标人名称:{bidder_name}。
                法人基本信息：{legal_person_dict}，{legal_person.name}系{bidder_name}(投标人名称) 的法定代表人 ,年龄为：{calculate_age(legal_person.birthday)}。
                委托代理人基本信息：{model_to_dict(company_agent)}，注意投标人名称是公司名称
                投标人（公司）基本情况表为:{ExCompany_data_name}，投标人（公司）基本情况表中字段说明为：{ExCompany_data_name_comments}
                输入输出样例为：
                        输入：'投标人名称：(),姓名：().'
                        输出：
                        ```json
                        ["xxx","xxx"]
                            ```
                需要基于基本信息，填充实际输入数据，将结果输出为json list
                
                ###第一步###
                先判断一下()内是否需要填写，如果不需要填写内容填写""空
                
                ###第二步###
                填写需要填写的()，如果不确定怎么填就填写""，括号()与填写的内容需要一一对应
                
                ###第三步###
                检查填写的内容是否一一对应，不允许有填写错位的情况
                
                '''
    if company_suitArbitrate:
        sszcqk_data = f'近年发生的诉讼及仲裁情况表:{[model_to_dict(suit) for suit in company_suitArbitrate]}'
    else:
        sszcqk_data = '''
                        近年发生的诉讼及仲裁情况表:近年发生的诉讼及仲裁情况表:["表格内容为：[['序号', '诉讼情况', '仲裁情况', '备注'], ['1', '无', '无', '无']]"]
                        '''
        # 11  正在履行和新承接的项目情况
    Doing_project_name = [model_to_dict(c_i) for c_i in Doing_project]
    # 获取字段备注
    Doing_project_name_comments = {
        field.name: field.help_text
        for field in ExProject._meta.get_fields()
        if hasattr(field, 'help_text')
    }
    xcjxm_data = f''' 正在履行和新承接的项目情况表为：{Doing_project_name}，表字段解释为：{Doing_project_name_comments} '''
    table_dict_excel = {"投标偏差表": tbpcb_prompt3,
                        "投标人基本情况": tbrjbqk_data,
                        "投标人关联企业": glqy_data,
                        "投标人重要信息": tbrzyxx_data,
                        '近年财务状况': jncwzk_data,
                        '近年发生的诉讼及仲裁情况': sszcqk_data,
                        '正在履行和新承接的项目': xcjxm_data

                        }
    # 法人正反面照片
    legal_person_IDCardFront = ExFile.objects.filter(id=legal_person.IDCardFront.id).first().path
    legal_person_IDCardBack = ExFile.objects.filter(id=legal_person.IDCardBack.id).first().path

    # 代理人正反面照片
    company_agent_IDCardFront = ExFile.objects.filter(id=company_agent.IDCardFront.id).first().path
    company_agent_IDCardBack = ExFile.objects.filter(id=company_agent.IDCardBack.id).first().path
    result_hj_data = [model_to_dict(award) for award in company_ExAward]
    # print('获奖数据:\n', result_hj_data)
    IDCard = [legal_person_IDCardFront, legal_person_IDCardBack, company_agent_IDCardFront, company_agent_IDCardBack]
    PM_ = bidPM.account
    if PM_.professional:
        PM_C=PM_.professional
    else:
        PM_C =''

    #查询业绩和负责人业绩累计金额
    pm_total_amount = Decimal('0.0')
    pm_projects = ExBidPmProject.objects.filter(bid=_id).select_related('project').distinct()
    for project in pm_projects:
        pm_total_amount += Decimal(str(project.project.contractAmount))

    total_amount = Decimal('0.0')
    pm_projects = ExBidProject.objects.filter(bid=_id).select_related('project').distinct()
    for project in pm_projects:
        total_amount += Decimal(str(project.project.contractAmount))

    finance_prompt = f'''
    公司近三年财务状况：{jncwzk_data}
    公司：业绩累计金额：({total_amount})万元
    项目负责人：业绩累计金额：({pm_total_amount})万元
    职称：职称或学位名称：({PM_C}) #副高 高级
    公司证书名称：{company_qualification_name}  公司资质证书名称
    奖项名称：  获奖{len(award_counts)}个（{Prize_c})
    获得“A级纳税人”年份数量：{company_integritymanage_content}
    
     输入输出样例为：
                输入：'投标人名称：(),姓名：().'
                输出：
                ```json
                ["xxx","xxx"]
                    ```
                需要基于基本信息，填充实际输入数据，一个括号且为空为一个需要填充的数值，将每个数值输出为json。
    '''
    # print('IDCard:', IDCard)
    import time
    start_time = time.time()
    # pool_sema = threading.BoundedSemaphore(5)

    # 使用函数
    import datetime
    # 获取当前时间
    current_time = datetime.datetime.now()
    # 格式化时间为字符串，例如 "2023-04-01_12-30-00"
    # formatted_time = current_time.strftime("%Y-%m-%d_%H-%M-%S")

    other_file_path = '/media/977GB/virtualbox/投标文件模板/19_需要提供的其他商务文件_电网管理平台.docx'

    #初始化
    global_thread_all[task_id] = {"basic_info_threadpool":[]}

    dict_paragraph = {}
    for i,catalog in enumerate(catalogs, start=1):

        try:

            # if catalog.generateFile:
            #     continue

            source_path = os.path.join(ROOT_FOLDER, catalog.sourceFile.path)
            file = os.path.split(source_path)[-1]
            file_name, f_ty = os.path.splitext(file)

            # if '专用资格' not in file_name:
            # if not ('近年完成' in file_name or '类似业绩情况' in file_name or '类似项目情况' in file_name):
            #     continue

            #生成文件路径
            generate_path = source_path.replace('/template/', '/result/')
            generate_folder = os.path.split(generate_path)[0]
            if not os.path.isdir(generate_folder):
                os.makedirs(generate_folder)

            # # 更新数据库
            # # 当前时间
            # current = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
            # # 插入到ex_file数据库
            # file_obj = ExFile.objects.create(path=generate_path.replace(ROOT_FOLDER, ''),
            #                                  type='docx',
            #                                  uploadDate=current)
            #
            # # 更新数据库
            # ExBidCatalog.objects.filter(id=catalog.id).update(generateFile=file_obj)
            #
            # continue

            # 项目负责人业绩和公司业绩为copy过去
            if '项目负责人' in file_name or '负责人情况' in file_name:

                # 查询项目负责人业绩的路径
                pmProject = company_ExBid.pmProject
                if not pmProject:
                    copyfile(source_path, generate_path)
                    continue
                else:
                    source_path = os.path.join(ROOT_FOLDER, pmProject.path)

                # 提取名称编号
                nums = re.findall(r'\d+', file_name)
                if nums:
                    num = nums[0]
                else:
                    num = 0

                modify_docx_number(num, source_path, generate_path)

                # 更新数据库
                # 当前时间
                current = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
                # 插入到ex_file数据库
                file_obj = ExFile.objects.create(path=generate_path.replace(ROOT_FOLDER, ''),
                                                 type='docx',
                                                 uploadDate=current)

                # 更新数据库
                ExBidCatalog.objects.filter(id=catalog.id).update(generateFile=file_obj)

            elif '近年完成' in file_name or '类似业绩情况' in file_name or '类似项目情况' in file_name:


                # 查询公司业绩的路径
                project = company_ExBid.project
                if not project:
                    copyfile(source_path, generate_path)
                    continue
                else:
                    source_path = os.path.join(ROOT_FOLDER, project.path)

                # 提取名称编号
                nums = re.findall(r'\d+', file_name)
                if nums:
                    num = nums[0]
                else:
                    num = 0
                modify_docx_number(num, source_path, generate_path)

                # 更新数据库
                # 当前时间
                current = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
                # 插入到ex_file数据库
                file_obj = ExFile.objects.create(path=generate_path.replace(ROOT_FOLDER, ''),
                                                 type='docx',
                                                 uploadDate=current)

                # 更新数据库
                ExBidCatalog.objects.filter(id=catalog.id).update(generateFile=file_obj)

            elif '专用资格' in file_name:
                #查询专业资格要求
                special = company_ExBid.package.special
                special = special if special else  ''
                special = '质量管控工程师、技术支持工程师'

                # 查询公司业绩的路径
                project = company_ExBid.project
                if not project:
                    copyfile(source_path, generate_path)
                    continue
                else:
                    source_path = os.path.join(ROOT_FOLDER, project.path)

                # 提取名称编号
                nums = re.findall(r'\d+', file_name)
                if nums:
                    num = nums[0]
                else:
                    num = 0
                modify_docx_number(num, source_path, generate_path, first_para=special)

                # 更新数据库
                # 当前时间
                current = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
                # 插入到ex_file数据库
                file_obj = ExFile.objects.create(path=generate_path.replace(ROOT_FOLDER, ''),
                                                 type='docx',
                                                 uploadDate=current)

                # 更新数据库
                ExBidCatalog.objects.filter(id=catalog.id).update(generateFile=file_obj)

            elif '其他商务文件' in file_name:

                # 打开现有的.docx文件

                # copyfile(other_file_path, generate_path)

                text_num = file_name.split('_')[0]

                generate_numbered_document(other_file_path, generate_path, int(text_num) - 1)

                # 更新数据库
                # 当前时间
                current = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
                # 插入到ex_file数据库
                file_obj = ExFile.objects.create(path=generate_path.replace(ROOT_FOLDER, ''),
                                                 type='docx',
                                                 uploadDate=current)

                # 更新数据库
                ExBidCatalog.objects.filter(id=catalog.id).update(generateFile=file_obj)

            else:
                if file.endswith("docx"):
                    print(i, catalog.sourceFile.path)

                    # print("source_path", source_path)
                    global_thread_all[task_id][file_name] = {'filename': file_name, '文本填充': [], '表格填充': [{}],"结构化数据填报":[{}]}
                    dict_paragraph = copy_docx(source_path, file_name, dict_paragraph, file, table_dict_excel,
                                               pro_text, base_prompt1, base_prompt2, config_params, task_id)

                elif file.endswith("xlsx"):
                    # 2_商务_商务结构化数据填报
                    generate_path = os.path.splitext(generate_path)[0] + '.docx'
                    if '结构化数据填报' in file:
                        # bib_name = '标包4：客户服务平台（南方区域统一电力交易平台V2.1-市场管理、现货结算等优化）建设项目'
                        bib_name = company_ExBid.bidPackage
                        write_xlsx(source_path, generate_path, file, bib_name)
                        # 更新数据库
                        # 当前时间
                        current = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
                        # 插入到ex_file数据库
                        file_obj = ExFile.objects.create(path=generate_path.replace(ROOT_FOLDER, ''),
                                                         type='docx',
                                                         uploadDate=current)

                        # 更新数据库
                        ExBidCatalog.objects.filter(id=catalog.id).update(generateFile=file_obj)
        except:
            # pass
            print(traceback.format_exc())

    for th in global_thread_all[task_id]['basic_info_threadpool']:
        th.start()
    for th in global_thread_all[task_id]['basic_info_threadpool']:
        threading.Thread.join(th)

    from datetime import datetime

    for i, catalog in enumerate(catalogs, start=1):

        source_path = os.path.join(ROOT_FOLDER, catalog.sourceFile.path)
        file = os.path.split(source_path)[-1]
        # 生成文件路径
        generate_path_ = source_path.replace('/template/', '/result/')
        generate_folder = os.path.split(generate_path_)[0]
        if not os.path.isdir(generate_folder):
            os.makedirs(generate_folder)
        # print('正在写文件',file)
        if file.endswith("docx"):
            file_name, f_ty = os.path.splitext(file)
            target_doc = Document()
            # 提取名称编号
            nums = re.findall(r'\d+', file_name)
            if nums:
                text_num = nums[0]
            else:
                text_num = 0
            # print('保存的文件路径为：',generate_path_)
            if file_name in dict_paragraph.keys():
                # try:
                write_content(dict_paragraph, target_doc, text_num,generate_path_,file_name,special_file,ROOT_FOLDER,function_data, IDCard,
                                   result_hj_data, project_name, bidder_name,targetname_,bidd_package_,config_params,finance_prompt,task_id, source_path)

                #更新数据库
                # 当前时间
                current = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
                # 插入到ex_file数据库
                file_obj = ExFile.objects.create(path=generate_path_.replace(ROOT_FOLDER, ''),
                                                 type='docx',
                                                 uploadDate=current)

                # 更新数据库
                ExBidCatalog.objects.filter(id=catalog.id).update(generateFile=file_obj)
                # except:
                #     print(traceback.format_exc())

    print('消耗时间为', time.time() - start_time)

# import os.path
# import time
# from bid.generate.models import *
# from zentao.settings import ROOT_FOLDER
# from shutil import copyfile
#
# def business_generate(catalogs, bid):
#     for catalog in catalogs:
#         # print(catalog.sourceFile.path)
#         #模拟生成商务文件
#         time.sleep(0.2)
#
#         generate_path = catalog.sourceFile.path.replace('/template/','/result/')
#         copyfile(os.path.join(ROOT_FOLDER,catalog.sourceFile.path), os.path.join(ROOT_FOLDER,generate_path))
#
#         # 当前时间
#         current = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
#
#         # 插入到ex_file数据库
#         file_obj = ExFile.objects.create(path=generate_path.replace(ROOT_FOLDER, ''),
#                                          type='docx',
#                                          uploadDate=current)
#
#         #更新数据库
#         ExBidCatalog.objects.filter(id=catalog.id).update(generateFile=file_obj)
#
#     # 更新状态为完成
#     ExBid.objects.filter(id=bid).update(techStatus='done')

